Answers:
您可以使用ncp模块。我觉得这就是你所需要的
npm install ncp并在30秒内完成工作。谢谢。
这是我无需任何额外模块即可解决此问题的方法。仅使用内置fs和path模块。
注意:这确实使用了fs的读/写功能,因此它不会复制任何元数据(创建时间等)。从节点8.5开始,有copyFileSync可用的函数调用OS复制功能,因此也复制元数据。我还没有测试它们,但是应该可以替换它们。(请参阅https://nodejs.org/api/fs.html#fs_fs_copyfilesync_src_dest_flags)
var fs = require('fs');
var path = require('path');
function copyFileSync( source, target ) {
var targetFile = target;
//if target is a directory a new file with the same name will be created
if ( fs.existsSync( target ) ) {
if ( fs.lstatSync( target ).isDirectory() ) {
targetFile = path.join( target, path.basename( source ) );
}
}
fs.writeFileSync(targetFile, fs.readFileSync(source));
}
function copyFolderRecursiveSync( source, target ) {
var files = [];
//check if folder needs to be created or integrated
var targetFolder = path.join( target, path.basename( source ) );
if ( !fs.existsSync( targetFolder ) ) {
fs.mkdirSync( targetFolder );
}
//copy
if ( fs.lstatSync( source ).isDirectory() ) {
files = fs.readdirSync( source );
files.forEach( function ( file ) {
var curSource = path.join( source, file );
if ( fs.lstatSync( curSource ).isDirectory() ) {
copyFolderRecursiveSync( curSource, targetFolder );
} else {
copyFileSync( curSource, targetFolder );
}
} );
}
}
javascript var fs = require('fs'); var path = require('path');
fs.copy或fs.copySync实际调用MacOS和Windows中的OS级复制功能,因此实际上是在复制文件。
fs.copyFile,如果您在Mac和Windows上浏览节点源时,会调用操作系统特定的功能来复制文件
有些模块支持复制文件夹及其内容。最受欢迎的将是扳手
// Deep-copy an existing directory
wrench.copyDirSyncRecursive('directory_to_copy', 'location_where_copy_should_end_up');
另一种选择是node-fs-extra
fs.copy('/tmp/mydir', '/tmp/mynewdir', function (err) {
if (err) {
console.error(err);
} else {
console.log("success!");
}
}); //copies directory, even if it has subdirectories or files
这是一个递归复制目录及其内容到另一个目录的函数:
const fs = require("fs")
const path = require("path")
/**
* Look ma, it's cp -R.
* @param {string} src The path to the thing to copy.
* @param {string} dest The path to the new copy.
*/
var copyRecursiveSync = function(src, dest) {
var exists = fs.existsSync(src);
var stats = exists && fs.statSync(src);
var isDirectory = exists && stats.isDirectory();
if (isDirectory) {
fs.mkdirSync(dest);
fs.readdirSync(src).forEach(function(childItemName) {
copyRecursiveSync(path.join(src, childItemName),
path.join(dest, childItemName));
});
} else {
fs.copyFileSync(src, dest);
}
};
fs.lstatSync代替fs.statSync)
linking没有复制..问题是当您修改链接文件的内容时,原始文件也会更改。
对于linux / unix操作系统,可以使用shell语法
const shell = require('child_process').execSync ;
const src= `/path/src`;
const dist= `/path/dist`;
shell(`mkdir -p ${dist}`);
shell(`cp -r ${src}/* ${dist}`);
而已!
fs-extra模块的工作原理很像。
安装fs-extra
$ npm install fs-extra
以下是将源目录复制到目标目录的程序。
// include fs-extra package
var fs = require("fs-extra");
var source = 'folderA'
var destination = 'folderB'
// copy source folder to destination
fs.copy(source, destination, function (err) {
if (err){
console.log('An error occured while copying the folder.')
return console.error(err)
}
console.log('Copy completed!')
});
参考文献
fs-extra:https : //www.npmjs.com/package/fs-extra
例如:的NodeJS教程 - Node.js的复制文件夹
这就是我个人要做的:
function copyFolderSync(from, to) {
fs.mkdirSync(to);
fs.readdirSync(from).forEach(element => {
if (fs.lstatSync(path.join(from, element)).isFile()) {
fs.copyFileSync(path.join(from, element), path.join(to, element));
} else {
copyFolderSync(path.join(from, element), path.join(to, element));
}
});
}
适用于文件夹和文件
我创建了一个小的工作示例,仅需几个步骤即可将源文件夹复制到另一个目标文件夹(基于使用ncp的@ shift66答案):
步骤1-安装ncp模块:
npm install ncp --save
第2步-创建copy.js(将srcPath和destPath vars修改为所需的值):
var path = require('path');
var ncp = require('ncp').ncp;
ncp.limit = 16;
var srcPath = path.dirname(require.main.filename); //current folder
var destPath = '/path/to/destination/folder'; //Any destination folder
console.log('Copying files...');
ncp(srcPath, destPath, function (err) {
if (err) {
return console.error(err);
}
console.log('Copying files complete.');
});
第3步-运行
node copy.js
对于节点10,这非常容易。
const FSP = require('fs').promises;
async function copyDir(src,dest) {
const entries = await FSP.readdir(src,{withFileTypes:true});
await FSP.mkdir(dest);
for(let entry of entries) {
const srcPath = Path.join(src,entry.name);
const destPath = Path.join(dest,entry.name);
if(entry.isDirectory()) {
await copyDir(srcPath,destPath);
} else {
await FSP.copyFile(srcPath,destPath);
}
}
}
这假定dest不存在。
require('util').promisify用fs.mkdir和fs.copyFile代替require('fs').promises,这是在V11.1仍处于试验阶段。
withFileTypes选择?因为这样可以节省您的stat通话时间
withFileTypes选项。
我已经在这里知道了很多答案,但是没有人以简单的方式回答。关于fs-exra 官方文档,您可以轻松完成
const fs = require('fs-extra')
// copy file
fs.copySync('/tmp/myfile', '/tmp/mynewfile')
// copy directory, even if it has subdirectories or files
fs.copySync('/tmp/mydir', '/tmp/mynewdir')
因为我只是构建一个简单的节点脚本,所以我不希望脚本的用户需要导入大量外部模块和依赖项,所以我戴上了帽子,并从bash中搜索了运行命令贝壳。
此node.js代码片段以递归方式将一个名为node-webkit.app的文件夹复制到一个名为build的文件夹中:
child = exec("cp -r node-webkit.app build", function(error, stdout, stderr) {
sys.print("stdout: " + stdout);
sys.print("stderr: " + stderr);
if(error !== null) {
console.log("exec error: " + error);
} else {
}
});
感谢dzone的Lance Pollard让我入门。
上面的代码段仅限于基于Unix的平台(例如Mac OS和Linux),但是类似的技术可能适用于Windows。
@ mallikarjun-m谢谢!
fs-extra做的事情,如果不提供回调,它甚至可以返回Promise!:)
const path = require('path')
const fs = require('fs-extra')
let source = path.resolve( __dirname, 'folderA')
let destination = path.resolve( __dirname, 'folderB')
fs.copy(source, destination)
.then(() => console.log('Copy completed!'))
.catch( err => {
console.log('An error occured while copying the folder.')
return console.error(err)
})
如果目录存在,则带有符号链接支持 +的那个不会抛出。
function copyFolderSync(from, to) {
try {
fs.mkdirSync(to);
} catch(e) {}
fs.readdirSync(from).forEach((element) => {
const stat = fs.lstatSync(path.join(from, element));
if (stat.isFile()) {
fs.copyFileSync(path.join(from, element), path.join(to, element));
} else if (stat.isSymbolicLink()) {
fs.symlinkSync(fs.readlinkSync(path.join(from, element)), path.join(to, element));
} else if (stat.isDirectory()) {
copyFolderSync(path.join(from, element), path.join(to, element));
}
});
}
此代码可以正常工作,将任何文件夹递归复制到任何位置。仅Windows。
var child=require("child_process");
function copySync(from,to){
from=from.replace(/\//gim,"\\");
to=to.replace(/\//gim,"\\");
child.exec("xcopy /y /q \""+from+"\\*\" \""+to+"\\\"");
}
非常适合我的基于文本的游戏,用于创建新玩家。
我尝试了fs-extra和copy-dir递归地复制文件夹。但我想要
所以我写了我自己的:
//node module for node 8.6+
var path=require("path");
var fs=require("fs");
function copyDirSync(src,dest,options){
var srcPath=path.resolve(src);
var destPath=path.resolve(dest);
if(path.relative(srcPath,destPath).charAt(0)!=".")
throw new Error("dest path must be out of src path");
var settings=Object.assign(Object.create(copyDirSync.options),options);
copyDirSync0(srcPath,destPath,settings);
function copyDirSync0(srcPath,destPath,settings){
var files=fs.readdirSync(srcPath);
if (!fs.existsSync(destPath)) {
fs.mkdirSync(destPath);
}else if(!fs.lstatSync(destPath).isDirectory()){
if(settings.overwrite)
throw new Error(`Cannot overwrite non-directory '${destPath}' with directory '${srcPath}'.`);
return;
}
files.forEach(function(filename){
var childSrcPath=path.join(srcPath,filename);
var childDestPath=path.join(destPath,filename);
var type=fs.lstatSync(childSrcPath).isDirectory()?"directory":"file";
if(!settings.filter(childSrcPath,type))
return;
if (type=="directory") {
copyDirSync0(childSrcPath,childDestPath,settings);
} else {
fs.copyFileSync(childSrcPath, childDestPath, settings.overwrite?0:fs.constants.COPYFILE_EXCL);
if(!settings.preserveFileDate)
fs.futimesSync(childDestPath,Date.now(),Date.now());
}
});
}
}
copyDirSync.options={
overwrite: true,
preserveFileDate: true,
filter: function(filepath,type){return true;}
};
和类似的函数mkdirs,它是mkdirp的替代方法
function mkdirsSync(dest) {
var destPath=path.resolve(dest);
mkdirsSync0(destPath);
function mkdirsSync0(destPath){
var parentPath=path.dirname(destPath);
if(parentPath==destPath)
throw new Error(`cannot mkdir ${destPath}, invalid root`);
if (!fs.existsSync(destPath)) {
mkdirsSync0(parentPath);
fs.mkdirSync(destPath);
}else if(!fs.lstatSync(destPath).isDirectory()){
throw new Error(`cannot mkdir ${destPath}, a file already exists there`);
}
}
}
我为在目录之间递归地复制(copyFileSync)或移动(renameSync)文件编写了此函数:
//copy files
copyDirectoryRecursiveSync(sourceDir, targetDir);
//move files
copyDirectoryRecursiveSync(sourceDir, targetDir, true);
function copyDirectoryRecursiveSync(source, target, move) {
if (!fs.lstatSync(source).isDirectory()) return;
var operation = move ? fs.renameSync : fs.copyFileSync;
fs.readdirSync(source).forEach(function (itemName) {
var sourcePath = path.join(source, itemName);
var targetPath = path.join(target, itemName);
if (fs.lstatSync(sourcePath).isDirectory()) {
fs.mkdirSync(targetPath);
copyDirectoryRecursiveSync(sourcePath, targetDir);
}
else {
operation(sourcePath, targetPath);
}
});}
如果您使用的是Linux,并且性能不是问题,则可以使用exec来自child_process模块的函数来执行bash命令:
const { exec } = require('child_process');
exec('cp -r source dest', (error, stdout, stderr) => {...});
在某些情况下,我发现此解决方案比下载整个模块甚至使用fs模块都更干净。
挑选包裹时要小心。某些文件(如copy-dir)不支持复制长度超过0x1fffffe8个字符的大文件。它将引发一些错误,例如:
buffer.js:630 Uncaught Error: Cannot create a string longer than 0x1fffffe8 characters
在我的一个项目中,我经历了类似的事情。最终,我不得不更改所使用的软件包并调整大量代码。我会说这不是一个非常愉快的经历。
如果需要多个源和多个目标副本,则可以使用更好的副本并编写如下内容:
// copy from multiple source into a directory
bCopy(['/path/to/your/folder1', '/path/to/some/file.txt'], '/path/to/destination/folder');
甚至 :
// copy from multiple source into multiple destination
bCopy(['/path/to/your/folder1', '/path/to/some/file.txt'], ['/path/to/destination/folder', '/path/to/another/folder']);
ncp就是cool虽然...您可能希望/应该承诺其功能为is super cool。既然您在使用它,请将其添加到tools文件中以重新使用它。
以下是Async和使用的工作版本Promises。
index.js
const {copyFolder} = require('./tools/');
return copyFolder(
yourSourcePath,
yourDestinationPath
)
.then(() => {
console.log('-> Backup completed.')
}) .catch((err) => {
console.log("-> [ERR] Could not copy the folder: ", err);
})
tools.js
const ncp = require("ncp");
/**
* Promise Version of ncp.ncp()
*
* This function promisifies ncp.ncp().
* We take the asynchronous function ncp.ncp() with
* callback semantics and derive from it a new function with
* promise semantics.
*/
ncp.ncpAsync = function (sourcePath, destinationPath) {
return new Promise(function (resolve, reject) {
try {
ncp.ncp(sourcePath, destinationPath, function(err){
if (err) reject(err); else resolve();
});
} catch (err) {
reject(err);
}
});
};
/**
* Utility function to copy folders asynchronously using
* the Promise returned by ncp.ncp().
*/
const copyFolder = (sourcePath, destinationPath) => {
return ncp.ncpAsync(sourcePath, destinationPath, function (err) {
if (err) {
return console.error(err);
}
});
}
module.exports.copyFolder = copyFolder;
解决此问题的最简单方法是仅使用“ fs”和“ Path”模块以及一些逻辑.....
如果需要,根文件夹中的所有文件都将使用“新名称”进行复制,只需设置版本号即可,即.......................“ var v ='您的目录名称'”
在文件名前缀V内容中添加文件名。
var fs = require('fs-extra');
var path = require('path');
var c = 0;
var i =0 ;
var v = "1.0.2";
var copyCounter = 0;
var directoryCounter = 0;
var directoryMakerCounter = 0;
var recursionCounter = -1;
var Flag = false;
var directoryPath = [] ;
var directoryName = [] ;
var directoryFileName = [];
var fileName;
var directoryNameStorer;
var dc = 0;
var route ;
if (!fs.existsSync(v)){
fs.mkdirSync(v);
}
var basePath = path.join(__dirname, v);
function walk(dir){
fs.readdir(dir, function(err, items) {
items.forEach(function(file){
file = path.resolve(dir, file);
fs.stat(file, function(err, stat){
if(stat && stat.isDirectory()){
directoryNameStorer = path.basename(file);
route = file;
route = route.replace("gd",v);
directoryFileName[directoryCounter] = route;
directoryPath[directoryCounter] = file;
directoryName[directoryCounter] = directoryNameStorer;
directoryCounter++;
dc++;
if (!fs.existsSync(basePath+"/"+directoryName[directoryMakerCounter])){
fs.mkdirSync(directoryFileName[directoryMakerCounter]);
directoryMakerCounter++;
}
}else{
fileName = path.basename(file);
if(recursionCounter >= 0){
fs.copyFileSync(file, directoryFileName[recursionCounter]+"/"+v+"_"+fileName, err => {
if(err) return console.error(err);
});
copyCounter++;
}else{
fs.copyFileSync(file, v+"/"+v+"_"+fileName, err => {
if(err) return console.error(err);
});
copyCounter++;
}
}
if(copyCounter + dc == items.length && directoryCounter > 0 && recursionCounter < directoryMakerCounter-1){
console.log("COPY COUNTER : "+copyCounter);
console.log("DC COUNTER : "+dc);
recursionCounter++;
dc = 0;
copyCounter = 0;
console.log("ITEM DOT LENGTH : "+items.length);
console.log("RECURSION COUNTER : "+recursionCounter);
console.log("DIRECOTRY MAKER COUNTER : "+directoryMakerCounter);
console.log(": START RECURSION : "+directoryPath[recursionCounter]);
walk(directoryPath[recursionCounter]); //recursive call to copy sub-folder
}
})
})
});
}
walk('./gd', function(err, data){ //Just Pass The Root Directory Which You Want to Copy
if(err) throw err;
console.log("done");
})
这是我做的:
let fs = require('fs');
let path = require('path');
然后:
let filePath = //your FilePath
let fileList = []
var walkSync = function(filePath, filelist)
{
let files = fs.readdirSync(filePath);
filelist = filelist || [];
files.forEach(function(file)
{
if (fs.statSync(path.join(filePath, file)).isDirectory())
{
filelist = walkSync(path.join(filePath, file), filelist);
}
else
{
filelist.push(path.join(filePath, file));
}
});
// Ignore hidden files
filelist = filelist.filter(item => !(/(^|\/)\.[^\/\.]/g).test(item));
return filelist;
};
然后调用方法:
This.walkSync(filePath, fileList)