是否有一種更簡單的方法來複制文件夾及其所有內容,而無需手動執行fs.readir
,fs.readfile
,fs.writefile
的遞歸序列?在node.js中遞歸複製文件夾
只是想知道如果我錯過了這會非常喜歡這個
fs.copy("/path/to/source/folder","/path/to/destination/folder");
是否有一種更簡單的方法來複制文件夾及其所有內容,而無需手動執行fs.readir
,fs.readfile
,fs.writefile
的遞歸序列?在node.js中遞歸複製文件夾
只是想知道如果我錯過了這會非常喜歡這個
fs.copy("/path/to/source/folder","/path/to/destination/folder");
有一些模塊支持複製文件夾的內容。最流行的是wrench
// 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
扳手失敗,如果目錄要複製包含符號鏈接 – DoubleMalt
它也失敗,如果該目錄已經存在,[ncp](https://npmjs.org/package/ncp)在包裏工作。 – blented
node-fs-extra爲我工作。它繼承了原始的fs,我喜歡它是處理過程的方式。在應用程序中更新的代碼較少。 – dvdmn
因爲我只是構建一個簡單的腳本節點,我不想腳本的用戶需要導入一堆外部模塊和依賴關係,所以我放了我的思想上限,並搜索了來自bash shell的運行命令。
這Node.js的代碼片段循環地將一個名爲node-webkit.app文件夾到一個文件夾,名爲編譯:
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 {
}
});
感謝Lance Pollard at dzone你爲我開始。
上面的代碼片段僅限於基於Unix的平臺,如Mac OS和Linux,但類似的技術可能適用於Windows。
/**
* 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 (exists && isDirectory) {
fs.mkdirSync(dest);
fs.readdirSync(src).forEach(function(childItemName) {
copyRecursiveSync(path.join(src, childItemName),
path.join(dest, childItemName));
});
} else {
fs.linkSync(src, dest);
}
};
可以優化爲'if(isDirectory) - 'isDirectory'已經檢查'exists'。 – Qix
這個功能不會複製它只是鏈接所有文件! –
即使你插入一個真正的複製函數,你也不應該遵循符號鏈接(使用'fs.lstatSync'而不是'fs.statSync') –
這是我的方法來解決這個問題,沒有任何額外的模塊。只需使用內置的fs
和path
模塊。
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);
}
});
}
}
它不會複製文件夾,如果他們的名字中有空格 – 31415926
對我來說,它會複製其名稱中包含空格的文件夾。也許這是由@victor糾正的錯誤引起的。由於我正在很經常地使用這個功能(在當前狀態下,因爲我忘記更新同樣的更正勝利者),所以我確信它一般工作。 –
@SimonZyx,'fs.createReadStream'不同步。將其更改爲'fs.writeFileSync(target,fs.readFileSync(source));'將使它成爲現實。 –
此代碼將工作得很好,遞歸地將任何文件夾複製到任何位置。僅限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+"\\\"");
}
完美適用於我的基於文本的遊戲來創建新玩家。
我創建了一個小型工作的例子,複製源文件夾到另一個目標文件夾中僅有幾步之遙(基於@ shift66答案使用NCP):
步驟1 - 安裝NCP模塊:
npm install ncp --save
第2步 - 創建副本。JS(修改srcPath和destPath瓦爾任何你需要的):
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
對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-額外
$ 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!')
});
參考
ncp
是cool
雖然...你可能想/應promisify其功能是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;
有沒有辦法做到這一點沒有任何模塊?也許遞歸函數/代碼片斷 - 它? – Sukima
@Sukima - 查看我的回答[here](http://stackoverflow.com/a/21321485/552792)。 – jmort253