繁体   English   中英

Node.js递归复制文件夹

[英]Copy folder recursively in Node.js

有没有更简单的方法来复制文件夹及其所有内容,而无需手动递归地执行fs.readirfs.readfilefs.writefile的序列?

我只是想知道我是否缺少 function 理想情况下可以这样工作:

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

关于这个历史性的问题。 请注意, fs.cpfs.cpSync可以递归复制文件夹,并且在 Node v16+ 中可用

有没有更简单的方法来复制文件夹及其所有内容,而无需手动递归执行fs.readirfs.readfilefs.writefile的序列?

我只是想知道我是否缺少一个理想地像这样工作的功能:

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

这是我在没有任何额外模块的情况下解决此问题的方法。 只需使用内置的fspath模块。

注意:这确实使用了 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 );
            }
        } );
    }
}

看起来ncpwrench都不再维护了。 可能最好的选择是使用fs-extra

Wrench 的开发者指示用户使用fs-extra ,因为他已经弃用了他的库

copySyncmoveSync都将复制和移动文件夹,即使它们有文件或子文件夹,您也可以使用它轻松移动或复制文件

const fse = require('fs-extra');

const srcDir = `path/to/file`;
const destDir = `path/to/destination/directory`;
                              
// To copy a folder or file  
fse.copySync(srcDir, destDir, function (err) {
  if (err) {                 ^
    console.error(err);      |___{ overwrite: true } // add if you want to replace existing folder or file with same name
  } else {
    console.log("success!");
  }
});

或者

// To Move a folder or file  
fse.moveSync(srcDir, destDir, function (err) {
  if (err) {                 ^
    console.error(err);      |___{ overwrite: true } // add if you want to replace existing folder or file with same name
  } else {
    console.log("success!");
  }
});

这是一个递归地将目录及其内容复制到另一个目录的函数:

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

有一些模块支持复制文件夹及其内容。 最受欢迎的是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

这就是我个人的做法:

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

它适用于文件夹和文件。

有没有更简单的方法来复制文件夹及其所有内容,而无需手动递归执行fs.readirfs.readfilefs.writefile的序列?

我只是想知道我是否缺少一个理想地像这样工作的功能:

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

对于 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-extra:

$ npm install fs-extra

以下是将源目录复制到目标目录的程序。

// Include the fs-extra package
var fs = require("fs-extra");

var source = 'folderA'
var destination = 'folderB'

// Copy the source folder to the destination
fs.copy(source, destination, function (err) {
    if (err){
        console.log('An error occurred while copying the folder.')
        return console.error(err)
    }
    console.log('Copy completed!')
});

参考

fs-extra: https ://www.npmjs.com/package/fs-extra

示例: Node.js 教程- Node.js 复制文件夹

从 Node v16.7.0 开始,可以使用fs.cpfs.cpSync函数。

fs.cp(src, dest, {recursive: true});

当前稳定性(在 Node v17.0.1 中)是Experimental

这对于 Node.js 10 来说非常简单:

const Path = require('path');
const FSP = require('fs').promises;

async function copyDir(src,dest) {
    const entries = await FSP.readdir(src, {withFileTypes: true});
    await FSP.mkdir(dest);
    for(let entry of entries) {
        const srcPath = Path.join(src, entry.name);
        const destPath = Path.join(dest, entry.name);
        if(entry.isDirectory()) {
            await copyDir(srcPath, destPath);
        } else {
            await FSP.copyFile(srcPath, destPath);
        }
    }
}

这假设dest不存在。

我知道这里已经有很多答案,但没有人以简单的方式回答。

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

我创建了一个小型工作示例,只需几个步骤即可将源文件夹复制到另一个目标文件夹(基于 shift66 使用 ncp 的回答):

第 1 步 - 安装 ncp 模块:

npm install ncp --save

第 2 步 - 创建 copy.js(将srcPathdestPath变量修改为您需要的任何内容):

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

具有符号链接支持的那个:

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

因为我只是在构建一个简单的 Node.js 脚本,我不希望脚本的用户需要导入一堆外部模块和依赖项,所以我戴上我的思考帽并搜索了运行命令Bash 外壳。

此 Node.js 代码片段递归地将名为 node-webkit.app 的文件夹复制到名为 build 的文件夹中:

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 {

    }
});

感谢dzone 的 Lance Pollard让我开始。

上面的代码片段仅限于基于 Unix 的平台,如 macOS 和 Linux,但类似的技术可能适用于 Windows。

Mallikarjun M,谢谢

fs-extra做了这件事,如果你不提供回调,它甚至可以返回一个Promise :)

const path = require('path')
const fs = require('fs-extra')

let source = path.resolve( __dirname, 'folderA')
let destination = path.resolve( __dirname, 'folderB')

fs.copy(source, destination)
  .then(() => console.log('Copy completed!'))
  .catch( err => {
    console.log('An error occurred while copying the folder.')
    return console.error(err)
  })

从节点 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,
  }
);

仔细注意recursive: true的使用。 这可以防止ERR_FS_EISDIR错误。

阅读更多关于节点文件系统文档

我尝试了 fs-extra 和 copy-dir 以递归方式复制文件夹。 但我希望它

  1. 正常工作(copy-dir 抛出不合理的错误)
  2. 在过滤器中提供两个参数:文件路径和文件类型(fs-extra 不告诉文件类型)
  3. 进行目录到子目录检查和目录到文件检查

所以我自己写了:

// Node.js module for Node.js 8.6+
var path = require("path");
var fs = require("fs");

function copyDirSync(src, dest, options) {
  var srcPath = path.resolve(src);
  var destPath = path.resolve(dest);
  if(path.relative(srcPath, destPath).charAt(0) != ".")
    throw new Error("dest path must be out of src path");
  var settings = Object.assign(Object.create(copyDirSync.options), options);
  copyDirSync0(srcPath, destPath, settings);
  function copyDirSync0(srcPath, destPath, settings) {
    var files = fs.readdirSync(srcPath);
    if (!fs.existsSync(destPath)) {
      fs.mkdirSync(destPath);
    }else if(!fs.lstatSync(destPath).isDirectory()) {
      if(settings.overwrite)
        throw new Error(`Cannot overwrite non-directory '${destPath}' with directory '${srcPath}'.`);
      return;
    }
    files.forEach(function(filename) {
      var childSrcPath = path.join(srcPath, filename);
      var childDestPath = path.join(destPath, filename);
      var type = fs.lstatSync(childSrcPath).isDirectory() ? "directory" : "file";
      if(!settings.filter(childSrcPath, type))
        return;
      if (type == "directory") {
        copyDirSync0(childSrcPath, childDestPath, settings);
      } else {
        fs.copyFileSync(childSrcPath, childDestPath, settings.overwrite ? 0 : fs.constants.COPYFILE_EXCL);
        if(!settings.preserveFileDate)
          fs.futimesSync(childDestPath, Date.now(), Date.now());
      }
    });
  }
}
copyDirSync.options = {
  overwrite: true,
  preserveFileDate: true,
  filter: function(filepath, type) {
    return true;
  }
};

还有一个类似的函数mkdirs ,它是 mkdirp 的替代品:

function mkdirsSync(dest) {
  var destPath = path.resolve(dest);
  mkdirsSync0(destPath);
  function mkdirsSync0(destPath) {
    var parentPath = path.dirname(destPath);
    if(parentPath == destPath)
      throw new Error(`cannot mkdir ${destPath}, invalid root`);
    if (!fs.existsSync(destPath)) {
      mkdirsSync0(parentPath);
      fs.mkdirSync(destPath);
    }else if(!fs.lstatSync(destPath).isDirectory()) {
      throw new Error(`cannot mkdir ${destPath}, a file already exists there`);
    }
  }
}

我为在目录之间递归地复制(copyFileSync)或移动(renameSync)文件编写了这个函数:

// Copy files
copyDirectoryRecursiveSync(sourceDir, targetDir);
// Move files
copyDirectoryRecursiveSync(sourceDir, targetDir, true);


function copyDirectoryRecursiveSync(source, target, move) {
    if (!fs.lstatSync(source).isDirectory())
        return;

    var operation = move ? fs.renameSync : fs.copyFileSync;
    fs.readdirSync(source).forEach(function (itemName) {
        var sourcePath = path.join(source, itemName);
        var targetPath = path.join(target, itemName);

        if (fs.lstatSync(sourcePath).isDirectory()) {
            fs.mkdirSync(targetPath);
            copyDirectoryRecursiveSync(sourcePath, targetPath);
        }
        else {
            operation(sourcePath, targetPath);
        }
    });
}

挑选包裹时要小心。 某些包(如 copy-dir)不支持复制长度超过 0X1FFFFFE8 个字符(约 537 MB)的大文件。

它会抛出一些错误,例如:

buffer.js:630 未捕获的错误:无法创建长度超过 0x1fffffe8 个字符的字符串

我在我的一个项目中经历过类似的事情。 最终,我不得不更改我正在使用的包并调整大量代码。 我会说这不是一次非常愉快的经历。

如果需要多个源和多个目标副本,您可以使用better-copy并编写如下内容:

// Copy from multiple source into a directory
bCopy(['/path/to/your/folder1', '/path/to/some/file.txt'], '/path/to/destination/folder');

甚至:

// Copy from multiple source into multiple destination
bCopy(['/path/to/your/folder1', '/path/to/some/file.txt'], ['/path/to/destination/folder', '/path/to/another/folder']);

使用shelljs

npm i -D shelljs

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

如果您在 Linux 上,并且性能不是问题,您可以使用child_process模块中的exec函数来执行 Bash 命令:

const { exec } = require('child_process');
exec('cp -r source dest', (error, stdout, stderr) => {...});

在某些情况下,我发现这个解决方案比下载整个模块甚至使用fs模块更干净。

打字稿版本

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

此代码可以正常工作,递归地将任何文件夹复制到任何位置。 但它只是 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 + "\\\"");
}

它非常适合用于创建新玩家的基于文本的游戏。

如果要递归复制源目录的所有内容,则需要将recursive选项作为true传递,并且 fs-extra 记录了try catch以进行sync

因为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)
}

这可能是使用异步生成器函数并使用for await循环进行迭代的可能解决方案。 此解决方案包括过滤掉一些目录的可能性,将它们作为可选的第三个数组参数传递。

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

有没有更简单的方法来复制文件夹及其所有内容,而无需手动递归执行fs.readirfs.readfilefs.writefile的序列?

我只是想知道我是否缺少一个理想地像这样工作的功能:

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

另一种使用 glob 通配符复制文件的方法。 使用它,您可以有选择地复制,例如/my/dir/**/*.js

const glob = require('glob');
const path = require('path');
const fs = require('fs');

function copy(from, to) { //accepting glob pattern
  const wildcard = from.indexOf('*') !== -1;
  const pattern = !wildcard && fs.lstatSync(from).isDirectory() ? `${from}/**/*` : from;
  glob.sync(pattern).forEach(file => {
    const fromDirname = path.dirname(from.replace(/\/\*.*/, '/wildcard'));
    const target = file.replace(fromDirname, to);
    const [targetDir, recursive] = [path.dirname(target), true];
    !fs.existsSync(targetDir) && fs.mkdirSync(targetDir, {recursive});
    fs.lstatSync(file).isDirectory() ? 
      fs.mkdirSync(target, {recursive}) : fs.copyFileSync(file, target);
  })
}

例子

copy('src/tools', 'dist')
copy('src/components/**/*', 'dist/elements')
copy('src/*.html', 'dist')
copy('src/*.css', 'dist')
copy('public/*', 'dist')

对于没有fs.cp的旧节点版本,我在紧要关头使用它以避免需要第三方库:

const fs = require("fs").promises;
const path = require("path");

const cp = async (src, dest) => {
  const lstat = await fs.lstat(src).catch(err => false);

  if (!lstat) {
    return;
  }
  else if (await lstat.isFile()) {
    await fs.copyFile(src, dest);
  }
  else if (await lstat.isDirectory()) {
    await fs.mkdir(dest).catch(err => {});

    for (const f of await fs.readdir(src)) {
      await cp(path.join(src, f), path.join(dest, f));
    }
  }
};

// sample usage
(async () => {
  const src = "foo";
  const dst = "bar";

  for (const f of await fs.readdir(src)) {
    await cp(path.join(src, f), path.join(dst, f));
  }
})();

相对于现有答案的优势(或差异化):

  • 异步
  • 忽略符号链接
  • 如果目录已经存在,则不会抛出(如果不希望出现,请不要捕获mkdir抛出)
  • 相当简洁

内联版

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);}" dist temp\dest

在“节点 14.20.0”上测试过,但假设它适用于节点 10.x?

来自 user8894303 和 mpen 的回答: https://stackoverflow.com/a/52338335/458321

如果在 package.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 })));\"",
    "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);}\"",
    "clean": "npm run rmrf -- 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支持

我是这样做的:

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

是的,虽然ncp cool ...

您可能想要/应该承诺它的功能以使其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);
})

文件工具.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;

解决这个问题的最简单方法是仅使用“fs”和“Path”模块以及一些逻辑......

如果您只想设置版本号,则使用新名称复制根文件夹中的所有文件,即“var v = 'Your Directory Name'”

在文件名前缀加上文件名的内容。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM