我有一些代码似乎无法修复。它看起来如下:
var childProcess = require('child_process');
var spawn = childProcess.spawn;
child = spawn('./simulator',[]);
child.stdout.on('data',
function(data){
console.log(data);
}
);
这一切都在我的web应用程序的后端,该应用程序正在运行特定类型的模拟。模拟器可执行文件是一个c程序,它运行一个循环,等待传递数据(通过其标准输入)。当模拟输入(即来自客户端)时,我解析输入,然后将数据写入子进程stdin,如下所示:
child.stdin.write(INPUTS);
现在返回的数据是40000字节。但数据似乎被分解成8192个字节的块。我试过修复c程序的标准输出缓冲区,但它没有修复。我想知道node.js对"data"事件的大小是否有限制?我需要它作为一块回来。
缓冲区块大小应用于节点中。您在节点之外所做的任何事情都无法解决问题。若不在消息传递协议中做一些额外的工作,就无法从节点获得您想要的内容。任何大于块大小的消息都将被分块。有两种方法可以处理这个问题。
- 如果在开始从C中流出之前就知道了总输出大小,那么在数据中预先设置消息长度,这样节点进程就知道在终止整个消息之前要提取多少块
- 确定一个可以附加到从C程序发送的消息中的特殊字符。当节点看到该字符时,您将结束该消息的输入
如果您在web应用程序中处理IO,那么您确实希望使用异步方法。你需要以下内容(未经测试)。文档中有一个很好的示例,说明如何使用Stream
API
var data = '';
child.stdout.on('data',
function(chunk){
data += chunk;
}
);
child.stdout.on('end',
function(){
// do something with var data
}
);
我遇到了同样的问题。我尝试了很多不同的事情,开始感到恼火。我试着在前面加上一些特殊的字符。也许我很愚蠢,但我就是做不好。
我遇到了一个名为linerstream的模块,它基本上解析每个块,直到它看到一个EOF
。你可以这样使用它:
process.stdout.pipe(new Linerstream()).on('data', (data) => {
// data here is complete and not chunked
});
重要的是,您必须使用以EOF
结尾的行将数据写入stdout
。否则,它不知道这就是结局。
我可以说这对我很有效。希望它能帮助其他人。
ppejovic的解决方案有效,但我更喜欢concat流。
var concat = require('concat-stream');
child.stdout.pipe(concat(function(data) {
// all your data ready to be used.
});
根据您的问题领域,有许多好的流帮助程序值得研究。看看substack的流手册。