【问题标题】:Reading from multiple CSV files and writing into one using streams从多个 CSV 文件读取并使用流写入一个
【发布时间】:2020-07-18 21:56:15
【问题描述】:

我的程序接收 CSV 文件并尝试将它们合并到一个 CSV 文件中。所有 CSV 文件都将具有相同的列。

我正在使用 fast-csv 包来解析和格式化 CSV 文件的行,但我无法将它们全部连续放入一个文件中。

我正在遍历文件并运行解析和格式化行的函数,但输出文件全是无序的,并且不包含文件中的所有数据。

我认为这是由于我用来循环不同 CSV 文件参数的“for”循环的同步特性,以及从不同流读取并尝试写入单个流的异步特性。

我正在寻找一些关于如何循环遍历每个文件参数的指导,但在继续下一个文件之前 - 为该文件完成解析、格式化和写入输出文件。

// Function that parses and formats the given file
function formatFile(paths, index) {
  // Initialize format options
  let formatOptions = {
    quoteHeaders: true,
    quoteColumns: true,
    escape: '\\'
  };

  // If the current file is the first file, write the headers of the file
  if (index === 0) {
    formatOptions.headers = true;
  // If the current file is not the first file, do not write the headers of the file
  } else {
    formatOptions.writeHeaders = false;
  }

  // Take in the current file as a readable stream
  fs.createReadStream(paths[index])
    // Parse the CSV file
    .pipe(csv.parse({ headers: true, escape: '\\' }))
    // Format the rows of the CSV file
    .pipe(csv.format(formatOptions))
    // Pipe the formatted data into the output CSV file
    .pipe(outputFile);
}

// Loop through each CSV file argument and run the formatFile function on each
for (let i = 0; i < filePaths.length; i++) {
  formatFile(filePaths, i);
}

【问题讨论】:

    标签: javascript node.js csv stream fast-csv


    【解决方案1】:

    使用承诺。

    // Function that parses and formats the given file
    function formatFile(paths, index) {
      // Initialize format options
      let formatOptions = {
        quoteHeaders: true,
        quoteColumns: true,
        escape: '\\'
      };
    
      // If the current file is the first file, write the headers of the file
      if (index === 0) {
        formatOptions.headers = true;
      // If the current file is not the first file, do not write the headers of the file
      } else {
        formatOptions.writeHeaders = false;
      }
    
      // Take in the current file as a readable stream
      const stream = fs.createReadStream(paths[index])
        // Parse the CSV file
        .pipe(csv.parse({ headers: true, escape: '\\' }))
        // Format the rows of the CSV file
        .pipe(csv.format(formatOptions))
        // Pipe the formatted data into the output CSV file
        .pipe(outputFile);
    
       return new Promise(resolve => stream.on('finish', resolve))
    }
    
    // Loop through each CSV file argument and run the formatFile function on each
    for (let i = 0; i < filePaths.length; i++) {
      await formatFile(filePaths, i);
    }
    

    包含 for 循环的函数必须是异步函数。

    【讨论】:

    • 感谢您的帮助!使用 Promise 是有意义的,但是我按照您的建议修改了我的项目,它只是遍历第一个文件并停止,而不是遍历其余文件。关于它为什么会这样做的任何想法?
    • 我猜'finish' 事件没有触发。也许它应该是'end' 事件?无论哪种方式,谷歌搜索“流管道完成时的节点回调”。收听该事件,并致电resolve()
    猜你喜欢
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 2017-08-27
    • 2021-04-02
    • 1970-01-01
    • 2020-04-26
    相关资源
    最近更新 更多