如何在node.js中流读取目录?

时间:2014-09-10 04:27:20

标签: javascript node.js

假设我有一个包含100K +甚至500k +文件的目录。我想用fs.readdir读取目录,但它的异步不是流。有人告诉我,在完成读取整个文件列表之前,异步使用内存。

那么解决方案是什么?我想用流方法readdir。我可以吗?

3 个答案:

答案 0 :(得分:7)

在现代计算机中,遍历具有500K文件的目录不算什么。当您在Node.js中异步fs.readdir时,它所做的只是读取指定目录中的文件名列表。它没有读取文件'内容。我刚刚在dir中测试了700K文件。加载此文件名列表只需21MB内存。

一旦你加载了这个文件名列表,你就可以通过设置一些并发限制来逐个或并行地遍历它们,你可以轻松地全部使用它们。例如:

var async = require('async'),
    fs = require('fs'),
    path = require('path'),
    parentDir = '/home/user';

async.waterfall([
    function (cb) {
        fs.readdir(parentDir, cb);
    },
    function (files, cb) {
        // `files` is just an array of file names, not full path.

        // Consume 10 files in parallel.
        async.eachLimit(files, 10, function (filename, done) {
            var filePath = path.join(parentDir, filename);

            // Do with this files whatever you want.
            // Then don't forget to call `done()`.
            done();
        }, cb);
    }
], function (err) {
    err && console.trace(err);

    console.log('Done');
});

答案 1 :(得分:1)

现在有一种异步迭代的方法!您可以这样做:

const dir = fs.opendirSync('/tmp')

for await (let file of dir) {
  console.log(file.name)
}

要将其转换为流:


const _pipeline = util.promisify(pipeline)
await _pipeline([
  Readable.from(dir),
  ... // consume!
])

答案 2 :(得分:-1)

对此仍然没有好的解决方案。节点还不那么成熟。

现代文件系统可以轻松处理目录中的数百万个文件。因此,正如您所建议的,您可以在大规模操作中为其提供理由。

底层C库按需遍历目录列表,一次一次。但是我见过的所有声称要进行迭代的节点实现都使用fs.readdir,它将所有内容尽快读取到内存中。

据我了解,您必须等待将libuv的新版本引入节点。然后让维护者解决这个旧问题。请参见https://github.com/nodejs/node/issues/583

的讨论