【问题标题】:nodejs: write multiple files in for loopnodejs:在for循环中写入多个文件
【发布时间】:2021-06-25 12:02:45
【问题描述】:

我还在学习 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 ... 放入一个数组并对其进行迭代。

感谢您的帮助。

【问题讨论】:

    标签: node.js


    【解决方案1】:

    您可以将 Promise 保存在数组中并使用 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);
    });
    

    【讨论】:

    • 效果很好。我会拿起你的答案。非常感谢!
    【解决方案2】:

    您可以在没有其他库的情况下使用递归来执行此操作。下面的代码将从一个数组中复制文件,等待前一个文件完成复制,然后再异步移动到下一个。

    使用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!')
        }
    })
    

    【讨论】:

      【解决方案3】:

      这是另一种方式

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

      【讨论】:

        【解决方案4】:

        第一步:安装fs-extra

        npm i -D fs-extra

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

        第 2 步:使用fs.outputFile 写入文件

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

        如果输出目录不存在,它们将被递归创建。

        祝你好运……

        【讨论】:

          猜你喜欢
          • 2021-07-06
          • 2011-10-25
          • 2014-08-21
          • 1970-01-01
          • 1970-01-01
          • 2012-06-27
          • 2014-07-29
          • 2016-08-29
          • 1970-01-01
          相关资源
          最近更新 更多