391 Stimmen

Node.js fs.readdir rekursive Verzeichnissuche

Irgendwelche Ideen für eine asynchrone Verzeichnissuche mit fs.readdir? Mir ist klar, dass wir eine Rekursion einführen und die Funktion read directory mit dem nächsten zu lesenden Verzeichnis aufrufen könnten, aber ich bin ein wenig besorgt, dass es nicht asynchron ist...

Irgendwelche Ideen? Ich habe mir angesehen node-walk was großartig ist, aber mir nicht nur die Dateien in einem Array liefert, wie es readdir tut. Obwohl

Ich suche eine Ausgabe wie...

['file1.txt', 'file2.txt', 'dir/file3.txt']

3voto

Szymon Wygnański Punkte 9996

Überprüfen Sie die final-fs Bibliothek. Sie bietet eine readdirRecursive Funktion:

ffs.readdirRecursive(dirPath, true, 'my/initial/path')
    .then(function (files) {
        // in the `files` variable you've got all the files
    })
    .otherwise(function (err) {
        // something went wrong
    });

2voto

Jay Punkte 17871

Eigenständige Umsetzung von Versprechen

Ich verwende die wenn.js Versprechensbibliothek in diesem Beispiel.

var fs = require('fs')
, path = require('path')
, when = require('when')
, nodefn = require('when/node/function');

function walk (directory, includeDir) {
    var results = [];
    return when.map(nodefn.call(fs.readdir, directory), function(file) {
        file = path.join(directory, file);
        return nodefn.call(fs.stat, file).then(function(stat) {
            if (stat.isFile()) { return results.push(file); }
            if (includeDir) { results.push(file + path.sep); }
            return walk(file, includeDir).then(function(filesInDir) {
                results = results.concat(filesInDir);
            });
        });
    }).then(function() {
        return results;
    });
};

walk(__dirname).then(function(files) {
    console.log(files);
}).otherwise(function(error) {
    console.error(error.stack || error);
});

Ich habe einen optionalen Parameter hinzugefügt includeDir die Verzeichnisse in die Dateiliste aufnimmt, wenn sie auf true .

2voto

mpen Punkte 253762

Pour Node 10.3+ hier ist ein for-await Lösung:

#!/usr/bin/env node

const FS = require('fs');
const Util = require('util');
const readDir = Util.promisify(FS.readdir);
const Path = require('path');

async function* readDirR(path) {
    const entries = await readDir(path,{withFileTypes:true});
    for(let entry of entries) {
        const fullPath = Path.join(path,entry.name);
        if(entry.isDirectory()) {
            yield* readDirR(fullPath);
        } else {
            yield fullPath;
        }
    }
}

async function main() {
    const start = process.hrtime.bigint();
    for await(const file of readDirR('/mnt/home/media/Unsorted')) {
        console.log(file);
    }
    console.log((process.hrtime.bigint()-start)/1000000n);
}

main().catch(err => {
    console.error(err);
});

Der Vorteil dieser Lösung besteht darin, dass Sie sofort mit der Verarbeitung der Ergebnisse beginnen können. So dauert es z. B. 12 Sekunden, um alle Dateien in meinem Medienverzeichnis zu lesen, aber wenn ich es auf diese Weise mache, erhalte ich das erste Ergebnis innerhalb weniger Millisekunden.

2voto

dat Punkte 1476

klaw y klaw-sync sind für diese Art von Dingen eine Überlegung wert. Diese waren Teil von node-fs-extra .

2voto

thSoft Punkte 20471

En recursive-readdir Modul verfügt über diese Funktionalität.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X