Node.js child_process exec的标准输出被缩短

在Node.js中,我使用了child_process模块​​的exec命令来调用Java中的一个algorithm,该algorithm返回大量的文本,然后parsing和使用。 我能够捕捉它,但是当它超过一定数量的行,内容被截断。

exec("sh target/bin/solver "+fields.dimx+" "+fields.dimy, function(error, stdout, stderr){ //do stuff with stdout } 

我已经尝试过使用setTimeouts和callback,但没有成功,但我确实感到这是因为我引用标准输出之前,它可以完全检索我的代码。 我已经testing过,stdout实际上是数据丢失首先发生的地方。 这不是一个asynchronous的问题。 我也在我的本地机器和Heroku上testing过,并且发生完全相同的问题,每次都在同一行号码处截断。

任何想法或build议可能有助于这个?

编辑:我已经试过在我的电脑( windowsdir /s并得到同样的问题(它看起来像一个错误),这段代码解决了我的问题:

 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); }) 

我有exec.stdout.on('结束')callback永远挂在@damphat解决scheme。

另一个解决scheme是增加exec选项中的缓冲区大小:请参阅这里的文档

 { encoding: 'utf8', timeout: 0, maxBuffer: 200*1024, //increase here killSignal: 'SIGTERM', cwd: null, env: null } 

引用:maxBuffer指定在stdout或stderr上允许的最大数据量 – 如果超过这个值,subprocess将被终止。 我现在使用以下内容:这不需要处理stdout中用逗号分隔的块的分隔部分,而不是公认的解决scheme。

 exec('dir /b /OD ^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) } ); 

这个问题的真正(最好的)解决scheme是使用spawn而不是exec。 正如本文所述 ,spawn更适合处理大量的数据:

child_process.exec返回subprocess的整个缓冲区输出。 默认情况下,缓冲区大小设置为200k。 如果subprocess返回的不止于此,程序将会以错误消息“Error:maxBuffer exceeded”的forms崩溃。 您可以通过在exec选项中设置更大的缓冲区大小来解决该问题。 但是你不应该这样做,因为exec并不意味着那些将巨大缓冲区返回给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"); });