是否有一种更简单的方法来复制文件夹及其所有内容,而无需手动执行一系列的fs。readir, fs。readfile, fs。writefile递归?
我只是想知道我是否错过了一个函数,理想情况下是这样工作的:
fs.copy("/path/to/source/folder", "/path/to/destination/folder");
关于这个历史问题。注意fs。Cp和fs。cpSync可以递归复制文件夹,在Node v16+中可用
是否有一种更简单的方法来复制文件夹及其所有内容,而无需手动执行一系列的fs。readir, fs。readfile, fs。writefile递归?
我只是想知道我是否错过了一个函数,理想情况下是这样工作的:
fs.copy("/path/to/source/folder", "/path/to/destination/folder");
关于这个历史问题。注意fs。Cp和fs。cpSync可以递归复制文件夹,在Node v16+中可用
当前回答
我是这样做的:
let fs = require('fs');
let path = require('path');
然后:
let filePath = // Your file path
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)
其他回答
这是我解决这个问题的方法,没有任何额外的模块。只使用内置的fs和path模块。
注意:这使用fs的读/写函数,所以它不复制任何元数据(创建时间等)。从Node.js 8.5开始,有一个copyFileSync函数可用,它调用操作系统复制函数,因此也复制元数据。我还没有测试它们,但它应该可以替换它们。(见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 );
}
} );
}
}
fs-extra模块工作起来很有魅力。
安装fs-extra:
$ npm install fs-extra
下面是将源目录复制到目标目录的程序。
// Include the fs-extra package
var fs = require("fs-extra");
var source = 'folderA'
var destination = 'folderB'
// Copy the source folder to the destination
fs.copy(source, destination, function (err) {
if (err){
console.log('An error occurred while copying the folder.')
return console.error(err)
}
console.log('Copy completed!')
});
参考文献
fs-extra: https://www.npmjs.com/package/fs-extra
示例:Node.js教程- Node.js复制文件夹
如果你在Linux上,性能不是问题,你可以使用child_process模块中的exec函数来执行一个Bash命令:
const { exec } = require('child_process');
exec('cp -r source dest', (error, stdout, stderr) => {...});
在某些情况下,我发现这个解决方案比下载整个模块甚至使用fs模块更简洁。
解决这个问题最简单的方法是只使用'fs'和'Path'模块和一些逻辑…
如果你只是想设置版本号,根文件夹中的所有文件都复制新名称,即" var 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");
})
看起来ncp和扳手都不再维护了。可能最好的选择是使用fs-extra
扳手的开发人员指导用户使用fs-extra,因为他已经弃用了他的库
copySync和moveSync都将复制和移动文件夹,即使他们有文件或子文件夹,你可以很容易地移动或复制文件使用它
const fse = require('fs-extra');
const srcDir = `path/to/file`;
const destDir = `path/to/destination/directory`;
// To copy a folder or file, select overwrite accordingly
try {
fs.copySync(srcDir, destDir, { overwrite: true|false })
console.log('success!')
} catch (err) {
console.error(err)
}
OR
// To Move a folder or file, select overwrite accordingly
try {
fs.moveSync(srcDir, destDir, { overwrite: true|false })
console.log('success!')
} catch (err) {
console.error(err)
}