我有一个二进制应用程序,它生成一个连续的json对象流(不是json对象的数组)。 Json对象有时可以跨越多行(仍然是一个有效的json对象但是被美化)。
我可以连接到此流并阅读它,而不会出现如下问题:
var child = require('child_process').spawn('binary', ['arg','arg']);
child.stdout.on('data', data => {
console.log(data);
});
Streams是缓冲区并随时发出数据事件,因此我使用readline模块来解析缓冲区为行,它可以为Json对象工作(我能够JSON.parse()行)它不会跨越多条线。
最佳解决方案是监听返回单个json对象的事件,如:
child.on('json', object => {
});
我注意到了流节点文档中的objectMode选项,但是我已经注意到了。以缓冲区格式获取流,所以我相信我无法使用它。
在pixl-json-stream,json-stream看了一下npm,但在我的意见中,这些都不符合目的。有单簧管对象流,但它需要根据事件从头开始构建json对象。
我没有控制json对象流,大多数时候一个对象在一行上,但是10-20%的时间json对象在多行上(\ n作为EOL)没有分隔符对象之间。每个新对象总是从一个新行开始。
示例流:
{ "a": "a", "b":"b" }
{ "a": "x",
"b": "y", "c": "z"
}
{ "a": "a", "b":"b" }
我必须有一个解决方案,我只是遗漏了一些明显的东西。宁愿找到合适的模块然后用regexp破解流解析器来处理这种情况。
答案 0 :(得分:2)
我建议尝试解析每一行:
const readline = require('readline');
const rl = readline.createInterface({
input: child.stdout
});
var tmp = ''
rl.on('line', function(line) {
tmp += line
try {
var obj = JSON.parse(tmp)
child.emit('json', obj)
tmp = ''
} catch(_) {
// JSON.parse may fail if JSON is not complete yet
}
})
child.on('json', function(obj) {
console.log(obj)
})
由于孩子是一个EventEmitter,所以可以调用child.emit('json',obj)。
答案 1 :(得分:0)
具有相同的要求,我很不舒服地强制要求新行支持readline,需要能够处理在流的中间开始读取(可能是JSON文档的中间),并且没有'喜欢不断解析和检查错误(似乎效率低下)。
因此我更喜欢使用clarinet
sax解析器,在我去的时候收集文档,并在解析完整个JSON文档后发出doc
个事件。
我刚刚将这个课程发表到NPM