nodejs 中复制文件和文件夹的多种方式

蚊子前端博客
发布于 2022-05-27 16:21
nodejs 中有多种复制文件的方式,我们一起来看看。

nodejs 中有多种复制文件的方式,我们一起来看看。

1. copyFile

copyFile()方法的操作最简单,可以直接将文件复制到目标目录中。

COPYJAVASCRIPT

fs.copyFile('./a.txt', './dist/b.txt');

异步地将 src 复制到 dest。 默认情况下,如果 dest 已经存在,则会被覆盖。 除了可能的异常之外,没有给回调函数提供任何参数。 Node.js 不保证复制操作的原子性。 如果在打开目标文件进行写入后发生错误,Node.js 将尝试删除目标文件。

但这个方法有一个缺点:目标目录一定要存在(它不会自动创建目录),若不存在时则会抛出异常。因此在使用 copyFile()方法时,一定要确保目录肯定存在,若不存在的话,则需要使用fs.mkdir()fs.mkdirSync()来创建目录。

而且,copyFile()不能复制目录。

2. readFile 和 writeFile

读取 src 文件的内容,然后再写入到目标文件中。

这种方式适合于,在复制过程中,需要修改内容的,再写入目标文件。

COPYJAVASCRIPT

fs.readFile('./a.txt', { encoding: 'utf8' }, (err, data) => { if (err) { console.error(err); return; } data = data.replace(/hello/gi, 'world'); fs.writeFile('./b.txt', data, (err) => { if (err) { console.error(err); } }); });

缺点与上面的 copyFile()一样,writeFile()只能在已存在的目录中才能写入文件,readFile()是用来读取文件内容的,因此也无法复制目录。

好处就是在复制过程中,可以修改内容。

3. createReadStream 和 createWriteStream

readFile 和 writeFile 是整块的操作数据,若文件比较大,则会系统资源造成压力。而 createReadStream 和 createWriteStream 是采用流的方式来操作数据。

COPYJAVASCRIPT

fs.createReadStream('./a.txt').pipe(fs.createWriteStream(`./b.txt`));

4. cp

nodejs 从 16.7.0 版本开始,新加入了一个fs.cp()方法,可以将整个目录结构从 src 异步地复制到 dest,包括子目录和文件。

该方法既可以复制某一个文件,也可以复制一个目录。当需要复制目录时,需要将配置中的recursive属性设置为 true。

复制文件:

COPYJAVASCRIPT

// 复制文件 fs.cp('./a.txt', './aa/b.txt', (err) => { if (err) { console.error(err); } });

复制整个目录,包括子目录:

COPYJAVASCRIPT

// 复制目录 fs.cp('./aa', './bb', { recursive: true }, (err) => { if (err) { console.error(err); } });

可以看到,该方法比前面的要好使很多:

  1. 不用再确保 dest 目录一定存在,若 dest 目录不存在,则会自动创建(无论几级目录);

  2. 可以完整地复制整个文件夹里的文件,包括子目录,不用再递归地单独进行复制;

唯一要做的,就是确认好 nodejs 版本!

若您的 nodejs 版本比较低,但又想复制文件夹中的所有文件,怎么办呢?除了可以下一节的 linux 原生 cp 命令,我们还可以用递归的方式来,来复制有的文件:

COPYJAVASCRIPT

/** * 复制文件夹到目标文件夹 * @param {string} src 源目录 * @param {string} dest 目标目录 * @param {function} callback 回调 */ const copyDir = (src, dest, callback) => { const copy = (copySrc, copyDest) => { fs.readdir(copySrc, (err, list) => { if (err) { callback(err); return; } list.forEach((item) => { const ss = path.resolve(copySrc, item); fs.stat(ss, (err, stat) => { if (err) { callback(err); } else { const curSrc = path.resolve(copySrc, item); const curDest = path.resolve(copyDest, item); if (stat.isFile()) { // 文件,直接复制 fs.createReadStream(curSrc).pipe(fs.createWriteStream(curDest)); } else if (stat.isDirectory()) { // 目录,进行递归 fs.mkdirSync(curDest, { recursive: true }); copy(curSrc, curDest); } } }); }); }); }; fs.access(dest, (err) => { if (err) { // 若目标目录不存在,则创建 fs.mkdirSync(dest, { recursive: true }); } copy(src, dest); }); };

使用方式:

COPYJAVASCRIPT

copyDir('./aa', './abc/ddd');

5. linux 中的 cp 命令

我们可以使用 child_process 中的execspawn等来执行 linux 中的原生命令。而linux 中的 cp 命令就是用来复制文件或者目录的。

COPYJAVASCRIPT

const { exec, spawn } = require('child_process'); exec('cp ./aa/a.txt ./bb/b.txt'); // 复制文件时,需要确保目标目录存在 exec('cp -r ./aa ./bb/cc/dd'); // 复制文件夹,目标目录可以自动创建 spawn('cp', ['-r', './aa', './bb/cc/dd']);
标签:
阅读(188)

公众号:

qrcode

微信公众号:前端小茶馆