是否有一种更简单的方法来复制文件夹及其所有内容,而无需手动执行一系列的fs。readir, fs。readfile, fs。writefile递归?

我只是想知道我是否错过了一个函数,理想情况下是这样工作的:

fs.copy("/path/to/source/folder", "/path/to/destination/folder");

关于这个历史问题。注意fs。Cp和fs。cpSync可以递归复制文件夹,在Node v16+中可用


当前回答

下面是一个递归复制目录及其内容到另一个目录的函数:

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);
  }
};

其他回答

下面是一个递归复制目录及其内容到另一个目录的函数:

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);
  }
};

如果你想递归复制源目录的所有内容,那么你需要将递归选项传递为true,并尝试通过fs-extra记录catch以进行同步

因为fs-extra完全替代了fs,所以你不需要导入基本模块

const fs = require('fs-extra');
let sourceDir = '/tmp/src_dir';
let destDir = '/tmp/dest_dir';
try {
  fs.copySync(sourceDir, destDir, { recursive: true })
  console.log('success!')
} catch (err) {
  console.error(err)
}

解决这个问题最简单的方法是只使用'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");
})

我知道这里已经有很多答案了,但是没有一个答案是简单的。

关于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')

这是我解决这个问题的方法,没有任何额外的模块。只使用内置的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 );
            }
        } );
    }
}