简体   繁体   English

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

[英]Stdout buffer issue using node child_process

I'm trying to execute curl using node child_process to get a JSON file (about 220Ko) from a shared folder in a local network.我正在尝试使用 node child_process 执行 curl 以从本地网络中的共享文件夹中获取 JSON 文件(大约 220Ko)。 But it actually returns a buffer problem that I can't get throught.但它实际上返回了一个我无法解决的缓冲区问题。 Here is my code:这是我的代码:

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

And here is the error I get:这是我得到的错误:

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)

You need to use and set the maxBuffer option when using child_process.exec .使用child_process.exec时需要使用并设置maxBuffer选项。 From the documentation :文档中:

maxBuffer specifies the largest amount of data allowed on stdout or stderr - if this value is exceeded then the child process is killed. maxBuffer指定 stdout 或 stderr 上允许的最大数据量 - 如果超过此值,则子进程将被终止。

The documentation also states that the default value of maxBuffer is 200KB.该文档还指出maxBuffer的默认值为 200KB。

As an example, the maximum buffer size is increased to 500KB in the following code:例如,在以下代码中,最大缓冲区大小增加到 500KB:

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

Additionally, you may want to read about http.get to see if it is capable of achieving what you are trying to do.此外,您可能想了解http.get以了解它是否能够实现您想要做的事情。

I had a similar issue and I fixed it moving from exec to spawn:我有一个类似的问题,我修复了它从 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);
});

Adding some explanation to the answers.为答案添加一些解释。

The exec command buffers the data before sending it to the parent process. exec 命令在将数据发送到父进程之前对其进行缓冲。 It is generally suitable for the commands producing the smaller output.它通常适用于产生较小输出的命令。 The above error occurred because the output generated by the execution of the command was larger than the max buffer size.出现上述错误是因为执行命令产生的输出大于最大缓冲区大小。 One way to solve the above issue is to specify the buffer size as answered by Tim Cooper.解决上述问题的一种方法是指定 Tim Cooper 回答的缓冲区大小。

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

Another solution is to use the spawn method which is generally faster compared to the exec and it does not buffer the data before sending.另一种解决方案是使用 spawn 方法,该方法通常比 exec 更快,并且它在发送前不缓冲数据。 It sends the data as a stream hence the problem of buffer size never occurs.它将数据作为流发送,因此永远不会出现缓冲区大小的问题。 The code snippet used by Isampaio. 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:有史以来最快的解决方案:

If this line outputs a buffer:如果此行输出缓冲区:

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

You just change it to:您只需将其更改为:

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

JS console will encode your buffer. JS 控制台将对您的缓冲区进行编码。

Or we can simply use: console.log(data.toString()) .或者我们可以简单地使用: console.log(data.toString())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM