管道流来编辑node.js中的csv文件

时间:2016-12-06 11:20:01

标签: node.js csv stream

我基本上是想:

  • 以流形式打开csv文件
  • 在每一行上进行一些操作
  • 将结果流式传输到第二个csv文件
在node.js中

这是我的代码:

var fs = require("fs");
var csv = require("csv");

var readStream = fs.createReadStream("input.csv");
var writeStream = fs.createWriteStream("output.csv");

var csvStream = csv
    .parse()
    .on("data", function(data){
    //do some stuff with data
    return(JSON.stringify(data));
    })
    .on("end", function(){
        console.log("done");
    })
    .on("error", function(error){
        console.log(error)
    });

(readStream.pipe(csvStream)).pipe(writeStream);

我得到" TypeError:无效的非字符串/缓冲区块"。我究竟做错了什么 ?我对node.js完全不熟悉,所以请详细说明你的答案。

2 个答案:

答案 0 :(得分:1)

您正在正确阅读数据。但是,使用return不是转换数据的正确方法。 CSV流不能同时输出未转换的数据(您在data事件处理程序中读取的数据)以及要转换为writeStream的转换数据。

要将pipe与writeStream一起使用,您需要一个输出转换数据的readableStream。这意味着在转换函数周围创建一个读/写流,并管道fileReader > csvReader > transformStream > writeStream。 将函数附加到csv阅读器的data事件更简单,但是您需要手动写入文件。

正确的代码可能会更加清晰:

var fs = require("fs");
var csv = require("csv");

var readStream = fs.createReadStream("input.csv"); // readStream is a read-only stream wit raw text content of the CSV file
var writeStream = fs.createWriteStream("output.csv"); // writeStream is a write-only stream to write on the disk

var csvStream = csv.parse(); // csv Stream is a read and write stream : it reads raw text in CSV and output untransformed records

csvStream.on("data", function(data) {
  //console.log(data)

  writeStream.write(JSON.stringify(data));
})
.on("end", function(){
    console.log("done");
})
.on("error", function(error){
    console.log(error)
});

readStream.pipe(csvStream)

答案 1 :(得分:1)

我基本上已经做到了:

已解析(读取csv字符串并写入对象和数组)
字符串化(读取对象和数组并写入csv字符串)
将所有内容通过管道传输到我的文件中

function readingAppendingAndWritingToCSVFile(readStream, writeStream) {
  const results = [];
  const p = new Promise((resolve, reject) => {
    readStream.pipe(csv.parse({ columns: true }))
    .on('data', (data) => {
      console.log('data --------------', data);
      data.name = 'somename'; // will add new column with same data in all rows
      console.log('data after pushing ----------', data);
      results.push(data);
    })
    .on('error', (err) => {
      console.log('error ------------', err);
      reject();
    })
    .on('finish', () => {
      console.log();
      console.log('all the csv strings parsed to objects -------------', results);
    })
    .pipe(csv.stringify({ header: true }))
    .pipe(writeStream);
  });
  return p;