Node.js使用find和head读取大文件目录

时间:2019-04-29 10:40:38

标签: node.js

在node.js中,我使用find生成文件,而不是使用fs.readdir来生成文件,该文件要慢得多:

scanDirStream: function (needle, params) {
            var options = {
                type: 'f',
                name: '*'
            };
            for (var attrname in params) { options[attrname] = params[attrname]; }
            return new Promise((resolve, reject) => {
                var opt = [needle];
                for (var k in options) {
                    var v = options[k];
                    if (!Util.empty(v)) {
                        opt.push('-' + k);
                        opt.push(v);
                    }
                };
                var res = '';
                var find = spawn('find', opt)
                find.stdout.on('data', _data => {
                    var buff = Buffer.from(_data, 'utf-8').toString();
                    if (buff != '') res += buff;
                })
                find.stderr.on('data', error => {
                    return reject(Buffer.from(error, 'utf-8').toString());
                });
                find.on('close', (_) => {
                    data = res.split('\n');
                    data = data.slice(0, data.length - 1);
                    return resolve(data);
                });
            });
        }//scanDirStream

你这样称呼

scanDirStream(path, { name: name }).then(files => console.log(files))

对于大型目录,在将列表返回到Node.js之前,我将进一步改进它以限制find的输出,因此可以使用到head的管道,例如:

find -type -f "*.mp3" | head -n 100

应该像

var head = spawn('head',['-n','100])
var find = spawn('find', opt)
head.stdin.pipe(find)
                find.stdout.on('data', _data => {
                    var buff = Buffer.from(_data, 'utf-8').toString();
                    if (buff != '') res += buff;
                })
                find.stderr.on('data', error => {
                    return reject(Buffer.from(error, 'utf-8').toString());
                });
                find.on('close', (_) => {
                    data = res.split('\n');
                    data = data.slice(0, data.length - 1);
                    return resolve(data);
                });

但是管道无法正常工作

1 个答案:

答案 0 :(得分:1)

管道应该从find.stdouthead.stdin,最终输出是从head.stdout出来的

因此,代码应如下所示:

find.stdout.pipe(head.stdin);

并将dataclose上的监听器附加到head

head.stdout.on('data', ...);

head.on('close', ...);

对于错误处理,您可以将侦听器同时附加到find.stderrhead.stderr上,因为两个命令中的任何一个或两个都可能发生错误。