是否有一种更简单的方法来复制文件夹及其所有内容,而无需手动执行一系列的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+中可用
当前回答
对于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'和'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");
})
有一些模块支持复制文件夹及其内容。最流行的是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
我知道这里已经有很多答案了,但是没有一个答案是简单的。
关于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')
这是我个人的做法:
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));
}
});
}
它适用于文件夹和文件。
这可能是一个可能的解决方案使用异步生成器函数和迭代等待循环。这个解决方案包括过滤掉一些目录的可能性,将它们作为可选的第三个数组参数传递。
import path from 'path';
import { readdir, copy } from 'fs-extra';
async function* getFilesRecursive(srcDir: string, excludedDir?: PathLike[]): AsyncGenerator<string> {
const directoryEntries: Dirent[] = await readdir(srcDir, { withFileTypes: true });
if (!directoryEntries.length) yield srcDir; // If the directory is empty, return the directory path.
for (const entry of directoryEntries) {
const fileName = entry.name;
const sourcePath = resolvePath(`${srcDir}/${fileName}`);
if (entry.isDirectory()) {
if (!excludedDir?.includes(sourcePath)) {
yield* getFilesRecursive(sourcePath, excludedDir);
}
} else {
yield sourcePath;
}
}
}
然后:
for await (const filePath of getFilesRecursive(path, ['dir1', 'dir2'])) {
await copy(filePath, filePath.replace(path, path2));
}