nodejs:在for循环中写入多个文件

时间:2017-07-11 16:43:22

标签: node.js

我还在学习nodejs。这个问题与其他几个问题有关(例如Writing multiple files a loop in Nodejs),但有点不同。它实际上非常简单。我想写一些文件,当它完成后,继续执行其他任务。

没有for循环,我这样做,

fs.readFile(f1.path, function(err, data) {
    fs.writeFile("/tmp/" + f1.path, data, function(err) {
        fs.readFile(f2.path, function(err, data) {
            fs.writeFile("/tmp/" + f2.path, data, function(err) {
                ...
                if (err) throw err;

                // do something when all files are written

如果我想使用for循环转换它,该怎么办?假设我可以将f1,f2 ...放入一个数组并迭代它们。

感谢您的帮助。

4 个答案:

答案 0 :(得分:3)

您可以在数组中保存承诺,并使用Promise.all等待它们全部完成:

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

const files = [f1, f2, ...];

function copyFile(source, destination) {
    const input = fs.createReadStream(source);
    const output = fs.createWriteStream(destination);
    return new Promise((resolve, reject) => {

        output.on('error', reject);
        input.on('error', reject);
        input.on('end', resolve);
        input.pipe(output);
    });
}

const promises = files.map(file => {
    const source = file.path;
    const destination = path.join('/tmp', file.path);
    // Use these instead of line above if you have files in different
    // directories and want them all at the same level:
    // const filename = path.parse(file.path).base;
    // const destination = path.join('/tmp', filename);
    return copyFile(source, destination);
});

Promise.all(promises).then(_ => {
    // do what you want
    console.log('done');
}).catch(err => {
    // handle I/O error
    console.error(err);
});

答案 1 :(得分:1)

您可以使用递归来执行此操作而无需其他库。下面的代码将从一个数组中复制文件,等待先前的文件完成复制,然后再异步进入下一个文件。

使用fs.readFile()fs.writeFile()

的方法
const fs = require('fs')
const path = require('path')

// your files array
let files = [f1, f2]

function copyFile (index, cb) {
  let file = files[index]
  let dest = path.join('/tmp', file.path)
  if (!file) {
    // done copying
    return cb(null)
  }
  fs.readFile(file.path, (err, data) => {
    if (err) {
      // return callback with error
      return cb(err)
    } else {
      fs.writeFile(dest, data, (err) => {
        if (err) {
          return cb(err)
        } else {
          copyFile(index + 1, cb)
        }
      })
    }
  })
}

copyFile(0, (err) => {
    if (err) {
      // Handle Error
        console.log(err)
    } else {
      console.log('Files Copied Successfully!')
    }
})

使用流的方法,在我看来更好

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

// your files array
let files = [f1, f2]

function copyFile(index, cb) {
    let file = files[index]
    let dest = path.join('/tmp', file.path)

    if (!file) {
        return cb(null)
    }

    let source = fs.createReadStream(file.path)
    let copy = fs.createWriteStream(dest)

    source.on('error', err => {
      // explicitly close writer
      copy.end()
      return cb(err)
    })

    copy.on('error', err => {
      return cb(err)
    })

    copy.on('finish', () => {
      copyFile(index + 1, cb)
    })

    source.pipe(copy)
}

copyFile(0, (err) => {
    if (err) {
      // Handle Error
        console.log(err)
    } else {
      console.log('Files Copied Successfully!')
    }
})

答案 2 :(得分:0)

这是另一种方式

    const fs = require("fs");
    const listOfFiles = [{fileName:"a.txt",data:"dummy data!"},{fileName:"b.txt",data:"dummy data b!"},{fileName:"c.txt",data:"dummy data c!"},{fileName:"d.txt",data:"dummy data d!"},{fileName:"e.txt",data:"dummy data e!"}];

    listOfFiles.reduce(function(curFile, nextFile){
            return writeData(nextFile).then();
    }, writeData);

    console.log("Another Code to be executed!");
    console.log("Another Code to be executed!");
    console.log("Another Code to be executed!");
    console.log("Another Code to be executed!");

    function writeData(params){
      return new Promise((resolve,reject)=>{
        fs.writeFile(params.fileName,params.data,'utf8',(err)=>{
           if(err)
              reject(err);
           else
              resolve();
          });
     });
}

答案 3 :(得分:0)

步骤1:安装fs-extra

npm i -D fs-extra

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

步骤2:使用fs.outputFile

写入文件
const fs = require('fs-extra');
// Async
outputFile(file, data, [options, callback])
// Sync
outputFileSync(file, data, [options])
  

如果不存在输出目录,则会以递归方式创建它们。

祝你好运...