使用节点 child_process 的标准输出缓冲区问题

我尝试使用 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)
93685 次浏览

在使用 child_process.exec时,您需要使用和设置 maxBuffer选项:

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,看看它是否能够实现你正在尝试做的事情。

我也遇到过类似的问题,所以我把它从一个 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);
});

给答案增加一些解释。

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

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

Fastest solution ever:

如果该行输出一个缓冲区:

childProc.stdout.on('data', (data) => console.log(data)); // <Buffer 1b 5b 34 6d>

你只要把它改成:

childProc.stdout.on('data', (data) => console.log(`${data}`)); // bla bla bla

JS 控制台将对缓冲区进行编码。

或者我们可以简单地使用: console.log(data.toString())