我正在构建一个节点应用程序,它从文件系统中读取CSV文件,分析文件,然后使用csv-parse
模块解析文件。这些步骤中的每一步都是流的形式,管道输入到下一步。
我遇到的问题是,对于某些文件,解析步骤可以读取流,但对于其他文件,read()
方法会在null
事件上返回readable
并且我不会#39;不知道为什么。
在下面的代码中,具体来说,我有时会在解析器流上调用read()
时看到数据,有时它会返回null
。成功的CSV文件始终成功,失败的CSV文件始终失败。我试图确定文件之间的一些区别,但除了在第一行中使用不同的字段名称,以及正文中的数据略有不同之外,我无法看到源文件之间存在任何显着差异。
read()
事件后节点流的null
函数可能会返回readable
的原因是什么?
示例代码:
var parse = require('csv-parse');
var fs = require('fs');
var stream = require('stream');
var byteCounter = new stream.Transform({objectMode : true});
byteCounter.setEncoding('utf8');
var totalBytes = 0;
// count the bytes we have read
byteCounter._transform = function (chunk, encoding, done) {
var data = chunk.toString();
if (this._lastLineData) {
data = this._lastLineData + data ;
}
var lines = data.split('\n');
// this is because each chunk will probably not end precisely at the end of a line:
this._lastLineData = lines.splice(lines.length-1,1)[0];
lines.forEach(function(line) {
totalBytes += line.length + 1 // we add an extra byte for the end-of-line
this.push(line);
}, this);
done();
};
byteCounter._flush = function (done) {
if (this._lastLineData) {
this.push(this._lastLineData);
}
this._lastLineData = null;
done();
};
// csv parser
var parser = parse({
delimiter: ",",
comment: "#",
skip_empty_lines: true,
auto_parse: true,
columns: true
});
parser.on('readable', function(){
var row;
while( null !== (row = parser.read()) ) {
// do stuff
}
});
// start by reading a file, piping to byteCounter, then pipe to parser.
var myPath = "/path/to/file.csv";
var options = {
encoding : "utf-8"
};
fs.createReadStream(myPath, options).pipe(byteCounter).pipe(parser);