是否有一种更简单的方法来复制文件夹及其所有内容,而无需手动执行一系列的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+中可用
当前回答
目前最上面的答案可以大大简化。
const path = require('path');
const fs = require('fs');
function recursiveCopySync(source, target) {
if (fs.lstatSync(source).isDirectory()) {
if (!fs.existsSync(target)) {
fs.mkdirSync(target);
}
let files = fs.readdirSync(source);
files.forEach((file) => {
recursiveCopySync(path.join(source, file), path.join(target, file));
});
} else {
if (fs.existsSync(source)) {
fs.writeFileSync(target, fs.readFileSync(source));
}
}
}
其他回答
内联版本
node -e "const fs=require('fs');const p=require('path');function copy(src, dest) {if (!fs.existsSync(src)) {return;} if (fs.statSync(src).isFile()) {fs.copyFileSync(src, dest);}else{fs.mkdirSync(dest, {recursive: true});fs.readdirSync(src).forEach(f=>copy(p.join(src, f), p.join(dest, f)));}}const args=Array.from(process.argv); copy(args[args.length-2], args[args.length-1]);" dist temp\dest
或者节点16.x+
node -e "const fs=require('fs');const args=Array.from(process.argv); fs.cpSync(args[args.length-2], args[args.length-1], {recursive: true});"
在“节点14.20.0”上测试,但假设它在节点10.x上工作?
来自user8894303和pen的回答:https://stackoverflow.com/a/52338335/458321
如果在包中使用,请务必转义引号。json脚本
package.json:
"scripts": {
"rmrf": "node -e \"const fs=require('fs/promises');const args=Array.from(process.argv); Promise.allSettled(args.map(a => fs.rm(a, { recursive: true, force: true })));\"",
"cp": "node -e \"const fs=require('fs');const args=Array.from(process.argv);if (args.length>2){ fs.cpSync(args[args.length-2], args[args.length-1], {recursive: true});}else{console.log('args missing', args);}\""
"copy": "node -e \"const fs=require('fs');const p=require('path');function copy(src, dest) {if (!fs.existsSync(src)) {return;} if (fs.statSync(src).isFile()) {fs.copyFileSync(src, dest);}else{fs.mkdirSync(dest, {recursive: true});fs.readdirSync(src).forEach(f=>copy(p.join(src, f), p.join(dest, f)));}}const args=Array.from(process.argv);if (args.length>2){copy(args[args.length-2], args[args.length-1]);}else{console.log('args missing', args);}\"",
"mkdir": "node -e \"const fs=require('fs');const args=Array.from(process.argv);fs.mkdirSync(args[args.length-1],{recursive:true});\"",
"clean": "npm run rmrf -- temp && npm run mkdir -- temp && npm run copy -- dist temp"
}
注:RMRF脚本需要14.20节点。X还是12.20.x?
奖金:
deno eval "import { existsSync, mkdirSync, copyFileSync, readdirSync, statSync } from 'node:fs';import { join } from 'node:path';function copy(src, dest) {if (!existsSync(src)) {return;} if (statSync(src).isFile()) {copyFileSync(src, dest);}else{mkdirSync(dest, {recursive: true});readdirSync(src).forEach(f=>copy(join(src, f), join(dest, f)));}}const args=Array.from(Deno.args);copy(args[0], args[1]);" dist temp\dest -- --allow-read --allow-write
Deno支持-> NPM I Deno -bin支持节点中的Deno -bin
从Node v16.7.0开始:
import { cp } from 'fs/promises';
await cp(
new URL('../path/to/src/', import.meta.url),
new URL('../path/to/dest/', import.meta.url), {
recursive: true,
}
);
注意使用递归:true。这可以防止ERR_FS_EISDIR错误。
阅读更多关于节点文件系统的文档
从Node v16.7.0开始,可以使用fs。Cp或fs。cpSync函数。
fs.cp(src, dest, {recursive: true});
电流稳定性(在节点v18.7.0中)是实验性的。
有一些模块支持复制文件夹及其内容。最流行的是wrench.js:
// 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
是的,ncp很酷…
你可能想要/应该承诺它的功能,让它超级酷。当你这样做的时候,把它添加到一个工具文件中以重复使用它。
下面是一个工作版本,它是异步的,并使用承诺。
文件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;