3

我有一些似乎无法修复的代码。它看起来如下:

var childProcess = require('child_process');
var spawn = childProcess.spawn;
child = spawn('./simulator',[]);

child.stdout.on('data',
    function(data){
        console.log(data);
    }
);

这一切都在我的 Web 应用程序的后端,该应用程序正在运行特定类型的模拟。模拟器可执行文件是一个 ac 程序,它运行一个循环等待传递数据(通过其标准输入)当输入进入模拟(即来自客户端)时,我解析输入,然后将数据写入子进程 stdin如下:

child.stdin.write(INPUTS);

现在返回的数据是 40,000 字节。但数据似乎被分成 8192 字节的块。我已经尝试修复 c 程序的标准输出缓冲区,但它没有修复它。我想知道 node.js 对“数据”事件的大小是否有限制?我需要它作为一大块回来。

4

4 回答 4

4

缓冲区块大小在节点中应用。您在节点之外所做的任何事情都无法解决问题。如果没有在消息传递协议中做一些额外的工作,就无法从节点获得你想要的东西。任何大于块大小的消息都将被分块。有两种方法可以处理此问题。

  1. 如果您在开始从 C 流出之前知道总输出大小,请将消息长度添加到数据中,以便节点进程知道在终止整个消息之前要提取多少块。
  2. 确定可以附加到从 C 程序发送的消息中的特殊字符。当节点看到该字符时,您结束该消息的输入。
于 2013-08-15T03:14:46.110 回答
3

如果您在 Web 应用程序中处理 IO,您真的想坚持使用异步方法。您需要以下内容(未经测试)。文档中有一个很好的示例说明如何使用StreamAPI

var data = '';
child.stdout.on('data',
    function(chunk){
        data += chunk;
    }
);    

child.stdout.on('end',
    function(){
        // do something with var data
    }
);
于 2013-08-14T23:19:36.447 回答
1

我遇到了同样的问题。我尝试了很多不同的事情,并开始生气。我尝试在前面加上特殊字符。也许我很愚蠢,但我就是做错了。

我遇到了一个名为linerstream的模块,它基本上解析每个块,直到它看到一个EOF. 你可以像这样使用它:

process.stdout.pipe(new Linerstream()).on('data', (data) => {
    // data here is complete and not chunked 
});

重要的部分是您必须使用以 .stdout结尾的行写入数据EOF。否则它不知道它是结束。

我可以说这对我有用。希望它可以帮助其他人。

于 2016-02-11T17:44:28.653 回答
0

ppejovic 的解决方案有效,但我更喜欢concat-stream

var concat = require('concat-stream');
child.stdout.pipe(concat(function(data) {
    // all your data ready to be used.
});

根据您的问题领域,有许多值得研究的优秀流助手。看看 substack 的stream-handbook

于 2013-08-15T00:54:33.590 回答