提问者:小点点

节点js:child-process.exec中的最大行数


节点的子进程有限制吗? 我怎样才能获取(一个块一个块地)一个巨大的命令输出,比如git show和一个巨大的文件呢?

我试图解析git show的结果,结果是一个巨大的文件(308 344行)

运行git show>时; showed_by_git.txt我有正确的输出,包括所有文件,结果为118 667行

当运行节点的子进程时,我只检索32 602行。。。

我简化了代码,并使用child-process在停止流之前计算字符数和它解析的行数。

结果表明,它停止在32 000多条线上,而不是预期的118 667条线上

如果您有一个存储库,其中包含最近提交的某个HUUUGE文件,那么您可以在家复制该文件

const childProcess = require('child_process')

function fetchCommand (command) {
  return new Promise((resolve, reject) => {
    const sub = childProcess.exec(command)

    let chars = 0
    let lines = 0

    sub.stdout.on('data', function (chunk) {
      chars += chunk.length
      lines += chunk.split('\n').length
      console.log('chars:' + chars + ' lines:' + lines)
      // logs the char and line count on each chunk of data, 
      // then 'forgets' the data : no memory overloading
    })
    sub.stdout.on('close', function () {
      console.log('CLOSED')
    })
    sub.stderr.on('error', function (err) {
      console.log('ERROR: ' + err.message)
    })
  })
}

fetchCommand('git show').catch(err => console.log(err))

以下是输出:

C:\Users\guill\.code\git2stats>node examples/fetchTest.js
chars:4096 lines:126
chars:73728 lines:2117
chars:131072 lines:3772
chars:176128 lines:5176
chars:229376 lines:6560
chars:262144 lines:7663
chars:323584 lines:9171
chars:393216 lines:11304
chars:462848 lines:13483
chars:475136 lines:13849
chars:507904 lines:14916
chars:536576 lines:15839
chars:573440 lines:17028
chars:618496 lines:18484
chars:688128 lines:20539
chars:737280 lines:22000
chars:765952 lines:22930
chars:794624 lines:23860
chars:823296 lines:24794
chars:892928 lines:26976
chars:962560 lines:29104
chars:991232 lines:30003
chars:1032192 lines:31292
chars:1073152 lines:32602
CLOSED

您可以看到它停止在32 602行,而这个特定的git show有118 667行要显示

我检查了最后一个数据块,看它是否对大文件做了什么特别的事情,但我可以确认它正好停在文件的中间

我正在编写一个git统计工具,这个程序非常好,因为我可以解析git日志--stat然后git show,为每个提交返回一个令人满意的json


共1个答案

匿名用户

这是一种我以前不知道的节点脚枪。

是的,是有限制的。 它使用maxbuffer选项进行配置(请参阅文档),如果您愿意,可以将其设置为无穷大。 这可以被设置为无穷大的想法并没有被记录下来。

const sub = childProcess.exec(command, { maxBuffer: Infinity });

老实说,我对这种限制的存在感到震惊,现在我将被迫对大量代码进行代码检查,以查找使用child_process模块的每个地方,并查看是否需要添加maxbuffer选项。

把它看作是一个如何糟糕地设计接口的例子。

您可能想要处理sub.on('exit',code=>{})sub.on('clos'),这是同一件事,因此您可以检查Git的退出状态,如果状态不是0,则会引发错误。 像这样的东西:

sub.on('exit', code => {
    if (code == 0) {
        resolve(...);
    } else {
        reject(...);
    }
});