节点的子进程
有限制吗? 我怎样才能获取(一个块一个块地)一个巨大的命令输出,比如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
这是一种我以前不知道的节点脚枪。
是的,是有限制的。 它使用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(...);
}
});