在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上测试了这个,并且出现完全相同的问题,每次都截断完全相同的行号。
关于可能对此有何帮助的任何想法或建议?
答案 0 :(得分:10)
我使用@damphat解决方案永远挂起了exec.stdout.on(' end')回调。
另一个解决方案是在exec的选项中增加缓冲区大小:请参阅文档here
{ 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)
}
);
答案 1 :(得分:8)
这个问题的真正(和最好)解决方案是使用spawn而不是exec。 如上所述in this article,spawn更适合处理大量数据:
child_process.exec返回子进程的整个缓冲区输出。默认情况下,缓冲区大小设置为200k。如果子进程返回的内容不止于此,则程序将崩溃并显示错误消息"错误:超出maxBuffer"。您可以通过在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");
});
答案 2 :(得分:4)
编辑:
我在我的计算机上尝试dir /s
(windows
)并遇到了同样的问题(看起来像个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);
})