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']

10voto

kalisjoshua Punkte 2084

Ich liebte die Antwort von chjj und wäre ohne diesen Start nicht in der Lage gewesen, meine Version der Parallelschleife zu erstellen.

var fs = require("fs");

var tree = function(dir, done) {
  var results = {
        "path": dir
        ,"children": []
      };
  fs.readdir(dir, function(err, list) {
    if (err) { return done(err); }
    var pending = list.length;
    if (!pending) { return done(null, results); }
    list.forEach(function(file) {
      fs.stat(dir + '/' + file, function(err, stat) {
        if (stat && stat.isDirectory()) {
          tree(dir + '/' + file, function(err, res) {
            results.children.push(res);
            if (!--pending){ done(null, results); }
          });
        } else {
          results.children.push({"path": dir + "/" + file});
          if (!--pending) { done(null, results); }
        }
      });
    });
  });
};

module.exports = tree;

Ich habe a Gist auch. Kommentare sind willkommen. Ich bin immer noch in der NodeJS Bereich beginnen, so dass ist ein Weg, ich hoffe, mehr zu lernen.

9voto

Andrew Odri Punkte 7660

Vanilla ES6 + async/await + klein und lesbar

Ich habe in diesem Thread nicht die Antwort gefunden, nach der ich gesucht habe; es gab ein paar ähnliche Elemente, die über verschiedene Antworten verteilt waren, aber ich wollte einfach etwas Einfaches und Lesbares.

Nur für den Fall, dass es irgendjemandem in der Zukunft hilft (z.B. mir selbst in ein paar Monaten), das habe ich letztendlich verwendet:

const { readdir } = require('fs/promises');
const { join } = require('path');

const readdirRecursive = async dir => {
  const files = await readdir( dir, { withFileTypes: true } );

  const paths = files.map( async file => {
    const path = join( dir, file.name );

    if ( file.isDirectory() ) return await readdirRecursive( path );

    return path;
  } );

  return ( await Promise.all( paths ) ).flat( Infinity );
}

module.exports = {
  readdirRecursive,
}

8voto

Tilo Punkte 575

Moderne, auf Versprechen basierende, rekursive Version von read dir:

const fs = require('fs');
const path = require('path');

const readDirRecursive = async (filePath) => {
    const dir = await fs.promises.readdir(filePath);
    const files = await Promise.all(dir.map(async relativePath => {
        const absolutePath = path.join(filePath, relativePath);
        const stat = await fs.promises.lstat(absolutePath);

        return stat.isDirectory() ? readDirRecursive(absolutePath) : absolutePath;
    }));

    return files.flat();
}

8voto

Verwenden Sie Knoten-Verzeichnis um genau die gewünschte Ausgabe zu erzeugen

var dir = require('node-dir');

dir.files(__dirname, function(err, files) {
  if (err) throw err;
  console.log(files);
  //we have an array of files now, so now we can iterate that array
  files.forEach(function(path) {
    action(null, path);
  })
});

8voto

Got To Figure Punkte 369

Hier ist eine einfache synchrone rekursive Lösung

const fs = require('fs')

const getFiles = path => {
    const files = []
    for (const file of fs.readdirSync(path)) {
        const fullPath = path + '/' + file
        if(fs.lstatSync(fullPath).isDirectory())
            getFiles(fullPath).forEach(x => files.push(file + '/' + x))
        else files.push(file)
    }
    return files
}

Verwendung:

const files = getFiles(process.cwd())

console.log(files)

Sie könnten es asynchron schreiben, aber das ist nicht nötig. Stellen Sie nur sicher, dass das Eingabeverzeichnis existiert und zugänglich ist.

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