使用节点child_process的stdout缓冲区问题

时间:2014-05-02 13:35:39

标签: javascript node.js

我尝试使用node child_process来执行curl,以从本地网络中的共享文件夹中获取JSON文件(大约220Ko)。但它实际上返回了我无法解决的缓冲问题。 这是我的代码:

var exec = require('child_process').exec;

var execute = function(command, callback){
    exec(command, function(error, stdout, stderr){ callback(error, stdout); });
};

execute("curl http://" + ip + "/file.json", function(err, json, outerr) {
    if(err) throw err;
    console.log(json);
})

这是我得到的错误:

if(err) throw err;
          ^
Error: stdout maxBuffer exceeded.
    at Socket.<anonymous> (child_process.js:678:13)
    at Socket.EventEmitter.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:746:14)
    at Socket.EventEmitter.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:408:10)
    at emitReadable (_stream_readable.js:404:5)
    at readableAddChunk (_stream_readable.js:165:9)
    at Socket.Readable.push (_stream_readable.js:127:10)
    at Pipe.onread (net.js:526:21)

3 个答案:

答案 0 :(得分:130)

使用maxBuffer时,您需要使用并设置child_process.exec选项。来自documentation

  

maxBuffer指定stdout或stderr上允许的最大数据量 - 如果超过此值,则子进程将被终止。

该文档还指出maxBuffer的默认值为200KB。

例如,在以下代码中,最大缓冲区大小增加到500KB:

var execute = function(command, callback){
    exec(command, {maxBuffer: 1024 * 500}, function(error, stdout, stderr){ callback(error, stdout); });
};

此外,您可能需要阅读http.get以了解它是否能够实现您的目标。

答案 1 :(得分:45)

我遇到了类似的问题,我修复了从exec到spawn的问题:

var child = process.spawn('<process>', [<arg1>, <arg2>]);

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

child.stderr.on('data', function (data) {
  console.log('stderr: ' + data);
});

child.on('close', function (code) {
    console.log('child process exited with code ' + code);
});

答案 2 :(得分:0)

在答案中添加一些解释。

exec命令在将数据发送到父进程之前先对其进行缓冲。通常适用于产生较小输出的命令。发生上述错误是因为执行命令所生成的输出大于最大缓冲区大小。解决上述问题的一种方法是根据Tim Cooper的回答指定缓冲区大小。

var execute = function(command, callback){
exec(command, {maxBuffer: 1024 * 500}, function(error, stdout, stderr){ 
 callback(error, stdout); });
};

另一种解决方案是使用spawn方法,该方法通常比exec更快,并且在发送之前不缓冲数据。它以流的形式发送数据,因此永远不会发生缓冲区大小的问题。 Isampaio使用的代码段。

var child = process.spawn('<process>', [<arg1>, <arg2>]);
child.stdout.on('data', function (data) {
 console.log('stdout: ' + data);
});
child.stderr.on('data', function (data) {
 console.log('stderr: ' + data);
});
child.on('close', function (code) {
 console.log('child process exited with code ' + code);
});