![](/img/trans.png)
[英]node.js child_process spawn stdout lower highWaterMark
[英]Stdout of Node.js child_process exec is cut short
在Node.js中,我使用了child_process模块的exec命令来调用Java中的算法,该算法将大量文本返回到标准输出,然后我将其解析和使用。 我能够捕获它,但是当它超过一定数量的行时,内容就会被截止。
exec("sh target/bin/solver "+fields.dimx+" "+fields.dimy, function(error, stdout, stderr){
//do stuff with stdout
}
我已经尝试过使用setTimeouts和回调但没有成功,但我确实感觉到这种情况正在发生,因为我在我的代码中引用了stdout,然后才能完全检索它。 我已经测试过stdout实际上是数据丢失首先发生的地方。 这不是一个异步问题。 我也在我的本地机器和Heroku上测试了这个,并且出现了完全相同的问题,每次都截断完全相同的行号。
关于什么可能对此有所帮助的任何想法或建议?
我用@damphat解决方案永远挂了exec.stdout.on('end')回调。
另一种解决方案是在exec的选项中增加缓冲区大小:请参阅此处的文档
{ encoding: 'utf8',
timeout: 0,
maxBuffer: 200*1024, //increase here
killSignal: 'SIGTERM',
cwd: null,
env: null }
引用:maxBuffer指定stdout或stderr上允许的最大数据量 - 如果超过此值,则子进程将被终止。 我现在使用以下内容:这不需要处理stdout中用逗号分隔的块的分隔部分,而不是接受的解决方案。
exec('dir /b /O-D ^2014*', {
maxBuffer: 2000 * 1024 //quick fix
}, function(error, stdout, stderr) {
list_of_filenames = stdout.split('\r\n'); //adapt to your line ending char
console.log("Found %s files in the replay folder", list_of_filenames.length)
}
);
这个问题的真正(和最好)解决方案是使用spawn而不是exec。 如本文所述 ,spawn更适合处理大量数据:
child_process.exec返回子进程的整个缓冲区输出。 默认情况下,缓冲区大小设置为200k。 如果子进程返回的内容不止于此,则程序将崩溃,并显示错误消息“Error:maxBuffer exceeded”。 您可以通过在exec选项中设置更大的缓冲区大小来解决该问题。 但是你不应该这样做,因为exec不适用于将HUGE缓冲区返回给Node的进程。 你应该使用spawn。 那么你用exec做什么? 使用它来运行返回结果状态而不是数据的程序。
spawn需要与exec不同的语法:
var proc = spawn('sh', ['target/bin/solver', 'fields.dimx', 'fields.dimy']);
proc.on("exit", function(exitCode) {
console.log('process exited with code ' + exitCode);
});
proc.stdout.on("data", function(chunk) {
console.log('received chunk ' + chunk);
});
proc.stdout.on("end", function() {
console.log("finished collecting data chunks from stdout");
});
编辑:我在我的计算机( windows
)上尝试使用dir /s
并遇到了同样的问题(看起来像一个bug),这段代码为我解决了这个问题:
var exec = require('child_process').exec;
function my_exec(command, callback) {
var proc = exec(command);
var list = [];
proc.stdout.setEncoding('utf8');
proc.stdout.on('data', function (chunk) {
list.push(chunk);
});
proc.stdout.on('end', function () {
callback(list.join());
});
}
my_exec('dir /s', function (stdout) {
console.log(stdout);
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.