我希望观看CSV文件,并在更改后获取最新记录。我运行以下shell命令来构建一个非常简单的csv文件并每秒追加一个新行:
rm test.csv & x=0 && while true; do echo "${x},${x},${x}" >> test.csv; x=$(($x+1)); sleep 1; done
以下代码打印文件的所有记录,直到第一次更改,然后只是发出虚线,就像它没有重新读取文件一样:
'use strict';
var fs = require('fs'),
dataFile = __dirname + '/server/data/test.csv',
csv = require('csv');
var parser = csv.parse({delimiter: ','}, function(err, data){
console.log(data);
});
var watcher = fs.watch(dataFile);
watcher.on('change', fileChange);
function fileChange(e, fn){
if (e) console.error(e)
fs.createReadStream(dataFile).pipe(parser);
console.log('-------')
}
fileChange
函数不应该在每次更改时重新读取文件吗?我在这里的最终计划是同时获取前一行和当前行,并使用lodash的difference
函数仅返回差异。如果有更好的方法,我可以听听它。
答案 0 :(得分:0)
我的猜测是fs.createReadStream()
已打开文件且未关闭。所以在第二个事件fs.createReadStream()
失败了。没有bueno。
尝试使用fs.readFile()
代替:
function fileChange(e, fn){
if (e) console.error(e)
fs.readFile(dataFile, function (err, data) {
if (err) throw err;
console.log(data);
console.log('-------')
});
};
请参阅此处的文档:http://nodejs.org/api/fs.html#fs_fs_readfile_filename_options_callback
答案 1 :(得分:0)
我最后通过声明更改文件并读取流数据的大小差异来解决问题:
'use strict';
var fs = require('fs'),
dataFile = __dirname + '/server/data/test.csv',
readSize = 0,
csv = require('csv');
var parser = csv.parse();
parser.on('readable', function(data){
var record;
while(record = parser.read()){
console.log(record);
}
});
var watcher = fs.watch(dataFile);
watcher.on('change', fileChange);
// fires when the watched file changes
function fileChange(e, fn){
// get these syncronously
var stats = fs.statSync(dataFile);
// if it's smaller, wait half a second
if (stats.size <= readSize) {
setTimeout(fileChange, 500);
}
// read the stream offset
var stream = fs.createReadStream(dataFile, {start: readSize, end: stats.size});
stream.on('data', function(chunk){
parser.write(chunk.toString());
});
readSize = stats.size;
}
对于为什么这可能不起作用的任何反馈将不胜感激。