【问题标题】:NodeJS - How to read multiple files asynchronously and write read contents to one fileNodeJS - 如何异步读取多个文件并将读取内容写入一个文件
【发布时间】:2016-12-25 12:46:38
【问题描述】:

我想在 NodeJS 中异步读取多个文件。当读取顺序无关紧要时,最好同时读取多个文件。

但是,我正在尝试将这些文件的内容一起写入一个文件。我可以写一个文件就好了,但是在我将所有内容写入该文件之前,如何确保所有文件都已被读取?

【问题讨论】:

    标签: node.js asynchronous read-write


    【解决方案1】:

    使用async

    'use strict';
    
    let fs = require('fs'),
        async = require('async'),
        inputs = ['in1', 'in2'],
        output = 'out';
    
    function fuse(inputs, output, callback) {
        async.map(inputs, (path, callback) => {
            fs.readFile(path, callback);
        }, (err, contents) => {
            if(error) {
                callback(error);
            } else {
                fs.writeFile(output, contents.reduce((a, b) => {
                    return a + b;
                }), callback);
            }
        });
    }
    
    fuse(inputs, output, (error) => {
        if(error) {
            console.log('Error: ' + error);
        } else {
            console.log('OK');
        }
    });
    

    编辑:

    使用承诺:

    'use strict';
    
    const fs = require('fs'),
        inputs = ['in1', 'in2'],
        output = 'out'
    
    // Promisify fs.readFile
    function read(file) {
        return new Promise((resolve, reject) => {
            fs.readFile(file, (error, data) => {
                if(error) {
                    reject(error);
                } else {
                    resolve(data);
                }
            });
        });
    }
    
    // Promisify fs.writeFile
    function write(file, data) {
        return new Promise((resolve, reject) => {
            fs.writeFile(file, data, (error) => {
                if(error) {
                    reject(error);
                } else {
                    resolve();
                }
            });
        });
    }
    
    Promise.all(inputs.map(read)) // Read all files
        .then((data) => { // data will be a array of the data in the files
            const outData = data.reduce((a, b) => {
                return a + b; // concatenate the data
            })
            return write(output, outData); // write the output
        })
        .then(() => {
            console.log('OK');
        })
        .catch((error) => {
            console.error(error);
        });
    

    (未经测试,但总体思路在这里) 正如 libik 所指出的,fs-promiseutil.promisifybluebird 是 promisify fs.readFilefs.writeFile 的替代品。

    【讨论】:

      【解决方案2】:

      通过以下方法之一的用户承诺

      1. 创建promise,每一个都在读取文件时解决
      2. 使用 bluebird 为 fs 创建类似 Promise 的方法
      3. 使用fs-promise模块

      然后将所有这些承诺保存到数组中并使用Promise.all

      其他方式可以是迭代变量,即var filesRead = 0。读取文件时,增加此数字filesRead++。在此之后,请始终检查,如果您读取了所有文件,如果是,您可以进行写入

      if (filesRead === numberOfFilesToRead){
          //write things
      }
      

      【讨论】:

        猜你喜欢
        • 2020-04-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-16
        • 2020-10-06
        • 1970-01-01
        • 2016-11-17
        • 2015-05-23
        相关资源
        最近更新 更多