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

44voto

Thorsten Lorenz Punkte 11563

Ein weiteres nettes npm-Paket ist Globus .

npm install glob

Es ist sehr leistungsfähig und sollte alle Ihre Bedürfnisse im Bereich der Wiederholung abdecken.

Editer :

Ich war nicht ganz zufrieden mit glob, also habe ich readdirp .

Ich bin sehr zuversichtlich, dass seine API das rekursive Auffinden von Dateien und Verzeichnissen und die Anwendung spezifischer Filter sehr einfach macht.

Lesen Sie sich seine Dokumentation um eine bessere Vorstellung davon zu bekommen, was es tut und via zu installieren:

npm install readdirp

36voto

Mir-Ismaili Punkte 10534

Kurz, modern und effizient:

import {lstat, readdir} from 'node:fs/promises'
import {join} from 'node:path'

const deepReadDir = async (dirPath) => await Promise.all(
  (await readdir(dirPath)).map(async (entity) => {
    const path = join(dirPath, entity)
    return (await lstat(path)).isDirectory() ? await deepReadDir(path) : path
  }),
)

Dadurch wird jeder verschachtelte Pfad automatisch in ein neues (verschachteltes) Array gefaltet. Zum Beispiel wenn:

const files = await deepReadDir('src')

files wäre wie:

[
  [
    'src/client/api.js',
    'src/client/http-constants.js',
    'src/client/index.html',
    'src/client/index.js',
    [ 'src/client/res/favicon.ico' ],
    'src/client/storage.js'
  ],
  [ 'src/crypto/keygen.js' ],
  'src/discover.js',
  [
    'src/mutations/createNewMutation.js',
    'src/mutations/newAccount.js',
    'src/mutations/transferCredit.js',
    'src/mutations/updateApp.js'
  ],
  [
    'src/server/authentication.js',
    'src/server/handlers.js',
    'src/server/quick-response.js',
    'src/server/server.js',
    'src/server/static-resources.js'
  ],
  [ 'src/util/prompt.js', 'src/util/safeWriteFile.js' ],
  'src/util.js'
]

Aber Sie können leicht Wohnung es:

files.flat(Number.POSITIVE_INFINITY)

[
  'src/client/api.js',
  'src/client/http-constants.js',
  'src/client/index.html',
  'src/client/index.js',
  'src/client/res/favicon.ico',
  'src/client/storage.js',
  'src/crypto/keygen.js',
  'src/discover.js',
  'src/mutations/createNewMutation.js',
  'src/mutations/newAccount.js',
  'src/mutations/transferCredit.js',
  'src/mutations/updateApp.js',
  'src/server/authentication.js',
  'src/server/handlers.js',
  'src/server/quick-response.js',
  'src/server/server.js',
  'src/server/static-resources.js',
  'src/util/prompt.js',
  'src/util/safeWriteFile.js',
  'src/util.js'
]

17voto

Domenic Punkte 104864

Wenn Sie ein npm-Paket verwenden möchten, Schraubenschlüssel ist ziemlich gut.

var wrench = require("wrench");

var files = wrench.readdirSyncRecursive("directory");

wrench.readdirRecursive("directory", function (error, files) {
    // live your dreams
});

EDIT (2018):
Jeder, der in letzter Zeit mitliest: Der Autor hat dieses Paket im Jahr 2015 veraltet:

wrench.js ist veraltet und wurde seit geraumer Zeit nicht mehr aktualisiert. Ich empfehle dringend die Verwendung von fs-extra um zusätzliche Dateisystemoperationen durchzuführen.

13voto

Afanasii Kurakin Punkte 3052

Asynchron

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

const readdir = (p, done, a = [], i = 0) => fs.readdir(p, (e, d = []) =>
  d.map(f => readdir(a[a.push(path.join(p, f)) - 1], () =>
    ++i == d.length && done(a), a)).length || done(a))

readdir(__dirname, console.log)

Sync

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

const readdirSync = (p, a = []) => {
  if (fs.statSync(p).isDirectory())
    fs.readdirSync(p).map(f => readdirSync(a[a.push(path.join(p, f)) - 1], a))
  return a
}

console.log(readdirSync(__dirname))

Asynchron lesbar

function readdir (currentPath, done, allFiles = [], i = 0) {
  fs.readdir(currentPath, function (e, directoryFiles = []) {
    if (!directoryFiles.length)
      return done(allFiles)
    directoryFiles.map(function (file) {
      var joinedPath = path.join(currentPath, file)
      allFiles.push(joinedPath)
      readdir(joinedPath, function () {
        i = i + 1
        if (i == directoryFiles.length)
          done(allFiles)}
      , allFiles)
    })
  })
}

readdir(__dirname, console.log)

Anmerkung: beide Versionen werden Symlinks folgen (wie das Original fs.readdir )

11voto

Loourr Punkte 4805

Mit Rekursion

var fs = require('fs')
var path = process.cwd()
var files = []

var getFiles = function(path, files){
    fs.readdirSync(path).forEach(function(file){
        var subpath = path + '/' + file;
        if(fs.lstatSync(subpath).isDirectory()){
            getFiles(subpath, files);
        } else {
            files.push(path + '/' + file);
        }
    });     
}

Aufruf von

getFiles(path, files)
console.log(files) // will log all files in directory

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