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

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

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

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


当前回答

这是我个人的做法:

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

它适用于文件夹和文件。

其他回答

使用 shelljs

npm i -D shelljs

const bash = require('shelljs');
bash.cp("-rf", "/path/to/source/folder", "/path/to/destination/folder");

我是这样做的:

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)

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

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 path = require("path");
const {
  existsSync,
  mkdirSync,
  readdirSync,
  lstatSync,
  copyFileSync,
  symlinkSync,
  readlinkSync,
} = require("fs");

export function copyFolderSync(src, dest) {
  if (!existsSync(dest)) {
    mkdirSync(dest);
  }

  readdirSync(src).forEach((entry) => {
    const srcPath = path.join(src, entry);
    const destPath = path.join(dest, entry);
    const stat = lstatSync(srcPath);

    if (stat.isFile()) {
      copyFileSync(srcPath, destPath);
    } else if (stat.isDirectory()) {
      copyFolderSync(srcPath, destPath);
    } else if (stat.isSymbolicLink()) {
      symlinkSync(readlinkSync(srcPath), destPath);
    }
  });
}

打印稿版本

async function copyDir(source: string, destination: string): Promise<any> {
  const directoryEntries = await readdir(source, { withFileTypes: true });
  await mkdir(destination, { recursive: true });

  return Promise.all(
    directoryEntries.map(async (entry) => {
      const sourcePath = path.join(source, entry.name);
      const destinationPath = path.join(destination, entry.name);

      return entry.isDirectory()
        ? copyDir(sourcePath, destinationPath)
        : copyFile(sourcePath, destinationPath);
    })
  );
}