Как получить список имен всех файлов, находящихся в каталоге в Node.js?

Я пытаюсь получить список имен всех файлов, находящихся в каталоге, с помощью Node.js. Мне нужен вывод, представляющий собой массив имен файлов. Как я могу это сделать?


person resopollution    schedule 28.04.2010    source источник
comment
fs.readdir работает, но не может использовать шаблоны подстановки имен файлов, такие как ls /tmp/*core*. Посетите github.com/isaacs/node-glob. Globs может даже искать в подкаталогах.   -  person Jess    schedule 02.12.2013
comment
Обратитесь к модулю NPM readdir-recursive, хотя, если вы также ищете имена файлов в подкаталогах   -  person Ethan Davis    schedule 11.06.2016
comment
метод es7 с ожиданием здесь   -  person Evan Carroll    schedule 29.04.2017
comment
fs.readdir - это простое асинхронное решение - примеры здесь   -  person drorw    schedule 18.04.2019
comment
Все еще не отвечаете с помощью итератора? Мне нужно просканировать 2,5 миллиона файлов… Я не хочу получать список из 2,5 м пути через 10 минут.   -  person Flavien Volken    schedule 13.05.2019
comment
@FlavienVolken, вы ищете nodejs.org/api/fs.html#fs_dir_read   -  person undefined    schedule 16.11.2020
comment
@undefined stackoverflow.com/questions/56298994/   -  person Flavien Volken    schedule 16.11.2020


Ответы (25)


Вы можете использовать fs.readdir или _ 2_. fs включен в ядро ​​Node.js, поэтому ничего устанавливать не нужно.

fs.readdir

const testFolder = './tests/';
const fs = require('fs');

fs.readdir(testFolder, (err, files) => {
  files.forEach(file => {
    console.log(file);
  });
});

fs.readdirSync

const testFolder = './tests/';
const fs = require('fs');

fs.readdirSync(testFolder).forEach(file => {
  console.log(file);
});

Разница между двумя методами заключается в том, что первый из них асинхронный, поэтому вы должны предоставить функцию обратного вызова, которая будет выполняться по завершении процесса чтения.

Второй - синхронный, он вернет массив имен файлов, но остановит дальнейшее выполнение вашего кода до завершения процесса чтения.

person Christian C. Salvadó    schedule 28.04.2010
comment
Примечание. readdir также показывает имена каталогов. Чтобы отфильтровать их, используйте fs.stat(path, callback(err, stats)) и _ 3_. - person Rob W; 03.06.2012
comment
Я должен добавить, что, скорее всего, вам следует использовать readdire, потому что вы не хотите блокировать ввод-вывод в узле. - person DragonKnight; 15.10.2015
comment
@ user3705055, если вы не используете gulp для чтения в каталоге файлов, зависящих от исходного порядка, и компиляции их в один исполняемый файл. - person r3wt; 07.04.2016
comment
comment
Я запуталась ... Не лучше ли использовать ls или dir /b/s для этой работы? Можно было бы подумать, что эти методы будут намного быстрее, чем итерация в Node ... - person Sancarn; 24.06.2017
comment
@Sancarn Вы хотите попробовать разобрать вывод ls? Просто подождите, пока кто-нибудь создаст имена файлов со встроенными пробелами и символами новой строки ... - person Radon Rosborough; 04.08.2017
comment
@RadonRosborough: да, недавно выяснилось, что ls не очень хорош для списков файлов. Но find неплохо справляется :) - person Sancarn; 04.08.2017
comment
Начиная с Node v10.10.0, комбинация параметра withFileTypes для функций readdir и readdirSync и метода isDirectory() может использоваться для фильтрации только файлов в каталоге - docs и пример здесь - person bnp887; 30.01.2019
comment
Спасибо за это! - person WhoIsCarlo; 08.04.2021
comment
Как бы вы сделали это в Typescript? Я получаю эту ошибку, когда пытаюсь сделать в машинописном тексте: TypeError: fs.readdir не является функцией Любая помощь приветствуется. - person Byusa; 31.05.2021

ИМО, наиболее удобный способ выполнять такие задачи - использовать инструмент glob. Вот пакет glob для node.js. Установить с помощью

npm install glob

Затем используйте подстановочный знак для сопоставления имен файлов (пример взят с веб-сайта)

var glob = require("glob")

// options is optional
glob("**/*.js", options, function (er, files) {
  // files is an array of filenames.
  // If the `nonull` option is set, and nothing
  // was found, then files is ["**/*.js"]
  // er is an error object or null.
})

Если вы планируете использовать globby, вот пример для поиска любых файлов xml, находящихся в текущей папке.

import globby = require('globby');

const paths = await globby("**/*.xml");  
person KFL    schedule 30.08.2014
comment
это было лучшее решение для меня, так как я хотел указать тип файла проще, чем сравнение строк. Спасибо. - person Pogrindis; 26.10.2014
comment
Мне это тоже нравится, потому что подстановка глобусов - почти фундаментальный навык в node. Если вы хотите просто вернуть имена файлов, передайте cwd в объекте параметров. - person jcollum; 02.09.2015
comment
Как получить результаты glob вне себя? Например. Я хочу console.log результаты, но не внутри glob()? - person Lanti; 09.02.2016
comment
@Lanti: может быть проще использовать метод glob.sync(pattern, [options]), поскольку он просто возвращает массив имен файлов, а не использует обратный вызов. Дополнительная информация здесь: github.com/isaacs/node-glob - person Glenn Lawrence; 07.06.2016
comment
Людям вроде меня, которые ищут реализацию glob с использованием обещаний, можно найти в globby от sindresorhus: github.com/sindresorhus/globby < / а> - person Nacho Coloma; 23.01.2018
comment
Я обновил ответ, добавив комментарий @NachoColoma и показав, как его использовать. - person Mauricio Gracia Gutierrez; 23.04.2021

Однако приведенный выше ответ не выполняет рекурсивный поиск в каталоге. Вот что я сделал для рекурсивного поиска (используя переход по узлам: npm install walk)

var walk    = require('walk');
var files   = [];

// Walker options
var walker  = walk.walk('./test', { followLinks: false });

walker.on('file', function(root, stat, next) {
    // Add this file to the list of files
    files.push(root + '/' + stat.name);
    next();
});

walker.on('end', function() {
    console.log(files);
});
person Ruben Tan    schedule 27.04.2011
comment
fs.readdirSync лучше, нативная альтернатива, созданная специально для этого. - person Eraden; 01.06.2012
comment
fs.readdirSync, к сожалению, не входит в подкаталоги, если только вы не хотите написать свою собственную процедуру для этого, чего вы не указали, что уже существуют модули npm для решения этой самой проблемы. - person Ruben Tan; 02.06.2012
comment
Вот ссылка на репозиторий github + документы: github.com/coolaj86/node-walk - person santiagoIT; 21.09.2012
comment
OP не спрашивал, какой API выполняет рекурсивное чтение. В любом случае принятый ответ дает то, что также может служить основой для выполнения рекурсивного чтения. - person Igwe Kalu; 19.08.2015
comment
Это фантастическая функция. Быстрый вопрос: есть ли быстрый способ игнорировать определенные директории? Я хочу игнорировать каталоги, начинающиеся с .git - person j_d; 03.05.2016
comment
Для более нового метода ES7 см. Мой ответ. - person Evan Carroll; 30.05.2016
comment
›Если вы не хотите писать свою собственную процедуру для этого, чего вы не знаете, что уже существуют модули npm для решения этой самой проблемы. пакет для этого! : / - person Danny Tuppeny; 31.03.2017
comment
Мне нравится этот. - person Saravanan Rajaraman; 27.06.2019

Получить файлы во всех подкаталогах

const fs=require('fs');

function getFiles (dir, files_){
    files_ = files_ || [];
    var files = fs.readdirSync(dir);
    for (var i in files){
        var name = dir + '/' + files[i];
        if (fs.statSync(name).isDirectory()){
            getFiles(name, files_);
        } else {
            files_.push(name);
        }
    }
    return files_;
}

console.log(getFiles('path/to/dir'))
person Tito100    schedule 11.12.2013
comment
Почему if (typeof files_ === 'undefined') files_=[];? вам нужно только var files_ = files_ || []; вместо files_ = files_ || [];. - person jkutianski; 03.12.2014
comment
Вы забыли добавить var fs = require('fs'); в начале getFiles. - person GFoley83; 01.07.2015
comment
Это рекурсивный метод. Он не поддерживает очень глубокие структуры папок, что приведет к переполнению стека. - person Mathias Lykkegaard Lorenzen; 16.04.2020
comment
@MathiasLykkegaardLorenzen Если у вас есть файловая система, вложенная в каталоги глубиной 11k, у вас, вероятно, есть много других вещей, о которых нужно беспокоиться: p - person Redwolf Programs; 29.04.2021
comment
Это не обязательно должно быть 11k. Это зависит от того, сколько данных помещено в стек, и этот метод имеет довольно большие выделения для стека. - person Mathias Lykkegaard Lorenzen; 29.04.2021

Вот простое решение, использующее только собственные модули fs и path:

// sync version
function walkSync(currentDirPath, callback) {
    var fs = require('fs'),
        path = require('path');
    fs.readdirSync(currentDirPath).forEach(function (name) {
        var filePath = path.join(currentDirPath, name);
        var stat = fs.statSync(filePath);
        if (stat.isFile()) {
            callback(filePath, stat);
        } else if (stat.isDirectory()) {
            walkSync(filePath, callback);
        }
    });
}

или асинхронная версия (вместо этого используется fs.readdir):

// async version with basic error handling
function walk(currentDirPath, callback) {
    var fs = require('fs'),
        path = require('path');
    fs.readdir(currentDirPath, function (err, files) {
        if (err) {
            throw new Error(err);
        }
        files.forEach(function (name) {
            var filePath = path.join(currentDirPath, name);
            var stat = fs.statSync(filePath);
            if (stat.isFile()) {
                callback(filePath, stat);
            } else if (stat.isDirectory()) {
                walk(filePath, callback);
            }
        });
    });
}

Затем вы просто звоните (для версии с синхронизацией):

walkSync('path/to/root/dir', function(filePath, stat) {
    // do something with "filePath"...
});

или асинхронная версия:

walk('path/to/root/dir', function(filePath, stat) {
    // do something with "filePath"...
});

Разница в том, как узел блокируется при выполнении ввода-вывода. Учитывая, что приведенный выше API такой же, вы можете просто использовать асинхронную версию для обеспечения максимальной производительности.

Однако у синхронной версии есть одно преимущество. Легче выполнить некоторый код сразу после завершения обхода, как в следующей инструкции после обхода. С асинхронной версией вам понадобится дополнительный способ узнать, когда вы закончите. Возможно, сначала создадим карту всех путей, а затем перечислим их. Для простых сценариев сборки / использования (по сравнению с высокопроизводительными веб-серверами) вы можете использовать синхронизирующую версию без какого-либо ущерба.

person Ali    schedule 03.02.2015
comment
Следует заменить строку в walkSync с walk(filePath, callback); на walkSync(filePath, callback); - person MIDE11; 07.02.2016
comment
Но вы все еще используете fs.statSync, который блокирует в асинхронной версии. Разве вам не следует использовать вместо этого fs.stat? - person MindlessRanger; 20.06.2016

Начиная с Node v10.10.0, можно использовать новую опцию withFileTypes для fs.readdir и fs.readdirSync в сочетании с функцией dirent.isDirectory() для фильтрации имен файлов в каталоге. Это выглядит так:

fs.readdirSync('./dirpath', {withFileTypes: true})
.filter(item => !item.isDirectory())
.map(item => item.name)

Возвращенный массив имеет вид:

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

Документы для класса fs.Dirent

person bnp887    schedule 30.01.2019
comment
это то, что люди ищут в 2020 году - следует закрепить - person Val Redchenko; 15.02.2020

Использование обещаний с ES7

Асинхронное использование с mz / fs

Модуль mz предоставляет обещанные версии библиотеки основных узлов. Использовать их просто. Сначала установите библиотеку ...

npm install mz

Потом...

const fs = require('mz/fs');
fs.readdir('./myDir').then(listing => console.log(listing))
  .catch(err => console.error(err));

В качестве альтернативы вы можете записать их в асинхронных функциях в ES7:

async function myReaddir () {
  try {
    const file = await fs.readdir('./myDir/');
  }
  catch (err) { console.error( err ) }
};

Обновление для рекурсивного листинга

Некоторые пользователи указали, что хотят видеть рекурсивный листинг (хотя не в вопросе) ... Используйте _5 _. Это тонкая оболочка для mz.

npm install fs-promise;

тогда...

const fs = require('fs-promise');
fs.walk('./myDir').then(
    listing => listing.forEach(file => console.log(file.path))
).catch(err => console.error(err));
person Evan Carroll    schedule 30.05.2016
comment
fs.walk удален из fs-обещания, поскольку он не поддерживается fs (github.com / kevinbeaty / fs-prom / issues / 28) - person adnan; 01.05.2017

нерекурсивная версия

Вы не говорите, что хотите делать это рекурсивно, поэтому я предполагаю, что вам нужны только прямые дочерние элементы каталога.

Образец кода:

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

fs.readdirSync('your-directory-path')
  .filter((file) => fs.lstatSync(path.join(folder, file)).isFile());
person Tyler Long    schedule 01.07.2016

Зависимости.

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

Определение.

// String -> [String]
function fileList(dir) {
  return fs.readdirSync(dir).reduce(function(list, file) {
    var name = path.join(dir, file);
    var isDir = fs.statSync(name).isDirectory();
    return list.concat(isDir ? fileList(name) : [name]);
  }, []);
}

Использование.

var DIR = '/usr/local/bin';

// 1. List all files in DIR
fileList(DIR);
// => ['/usr/local/bin/babel', '/usr/local/bin/bower', ...]

// 2. List all file names in DIR
fileList(DIR).map((file) => file.split(path.sep).slice(-1)[0]);
// => ['babel', 'bower', ...]

Обратите внимание, что fileList слишком оптимистичен. Для чего-нибудь серьезного добавьте немного обработки ошибок.

person Hunan Rostomyan    schedule 13.11.2015
comment
Я также добавил аргумент массива excludeDirs. Он меняет его достаточно, так что, возможно, вам стоит отредактировать его вместо этого (если вы этого хотите). В противном случае я добавлю это в другом ответе. gist.github.com/AlecTaylor/f3f221b4fb86b4375650 - person A T; 14.01.2016
comment
@AT Отлично! Вы должны опубликовать свой собственный ответ, так как это полезное расширение. Давайте оставим этот безликий. - person Hunan Rostomyan; 14.01.2016

Я предполагаю из вашего вопроса, что вам не нужны имена каталогов, а только файлы.

Пример структуры каталогов

animals
├── all.jpg
├── mammals
│   └── cat.jpg
│   └── dog.jpg
└── insects
    └── bee.jpg

Walk функция

Кредиты отправляются Джастину Майеру в эта суть

Если вы хотите просто массив путей к файлам, используйте return_object: false:

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

async function walk(dir) {
    let files = await fs.readdir(dir);
    files = await Promise.all(files.map(async file => {
        const filePath = path.join(dir, file);
        const stats = await fs.stat(filePath);
        if (stats.isDirectory()) return walk(filePath);
        else if(stats.isFile()) return filePath;
    }));

    return files.reduce((all, folderContents) => all.concat(folderContents), []);
}

использование

async function main() {
   console.log(await walk('animals'))
}

Выход

[
  "/animals/all.jpg",
  "/animals/mammals/cat.jpg",
  "/animals/mammals/dog.jpg",
  "/animals/insects/bee.jpg"
];
person a.barbieri    schedule 13.02.2020
comment
@justmaier & a.barbieri - спасибо за код и ответ! - person KyleMit; 19.09.2020
comment
привет, если я хочу показать и папку, что мне делать? например `[/animals/all.jpg, / animals / mammals /animals/mammals/cat.jpg, /animals/mammals/dog.jpg, /animals/insects/bee.jpg]; `любое решение - person Aakash; 02.04.2021
comment
Привет, @Aakash, попробуйте добавить files.unshift(dir) перед последним return функции async. В любом случае было бы лучше, если бы вы могли создать новый вопрос, так как он может помочь другим людям с той же потребностью и получить лучшую обратную связь. ;-) - person a.barbieri; 06.04.2021
comment
привет @ a.barbieri, а что, если я хочу читать только начальную двухуровневую папку, что мне нужно сделать, например: мой каталог выглядит так animals/mammals/name, и я хочу остановиться на млекопитающих, предоставив некоторую глубину [ "/animals/all.jpg", "/animals/mammals/cat.jpg", "/animals/mammals/dog.jpg", "/animals/insects/bee.jpg" ]; - person Aakash; 08.04.2021
comment
Пожалуйста, создайте новый вопрос и скопируйте / вставьте ссылку сюда, в комментарии. Буду рад ответить. - person a.barbieri; 09.04.2021

если кто-то все еще ищет это, я делаю это:

import fs from 'fs';
import path from 'path';

const getAllFiles = dir =>
    fs.readdirSync(dir).reduce((files, file) => {
        const name = path.join(dir, file);
        const isDirectory = fs.statSync(name).isDirectory();
        return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name];
    }, []);

и его работа очень хороша для меня

person Josh    schedule 27.01.2019
comment
Отлично сработал для меня, И это рекурсивно. Просто помните, что синтаксис импорта все еще находится за флагом в Node, возможно, вам придется пойти по старому пути: const fs = require ('fs'); - person mjsarfatti; 13.05.2019
comment
@Josh Это работает как шарм. Однако мне трудно понять, как работает [...files, ...getAllFiles(name)] или [...files, name]. Небольшое объяснение было бы очень полезно :) - person Md Mazedul Islam Khan; 02.02.2020
comment
@MdMazedulIslamKhan Используемый здесь ... называется синтаксисом распространения. По сути, он берет все объекты внутри массива и «распределяет» их по новому массиву. В этом случае все записи внутри массива files добавляются к возврату вместе со всеми значениями, возвращаемыми из рекурсивного вызова. Вы можете сослаться на синтаксис распространения здесь: developer.mozilla .org / en-US / docs / Web / JavaScript / Reference / - person T90; 06.03.2020

Загрузить fs:

const fs = require('fs');

Прочитать файлы async:

fs.readdir('./dir', function (err, files) {
    // "files" is an Array with files names
});

Прочитать файлы синхронизировать:

var files = fs.readdirSync('./dir');
person Eduardo Cuomo    schedule 13.09.2016

Получите sorted имена файлов. Вы можете фильтровать результаты по определенному extension, например, '.txt', '.jpg' и так далее.

import * as fs from 'fs';
import * as Path from 'path';

function getFilenames(path, extension) {
    return fs
        .readdirSync(path)
        .filter(
            item =>
                fs.statSync(Path.join(path, item)).isFile() &&
                (extension === undefined || Path.extname(item) === extension)
        )
        .sort();
}
person Yas    schedule 21.02.2018

Из коробки

Если вам нужен готовый объект со структурой каталогов, я настоятельно рекомендую вам проверить дерево каталогов.

Допустим, у вас есть такая структура:

photos
│   june
│   └── windsurf.jpg
└── january
    ├── ski.png
    └── snowboard.jpg
const dirTree = require("directory-tree");
const tree = dirTree("/path/to/photos");

Вернусь:

{
  path: "photos",
  name: "photos",
  size: 600,
  type: "directory",
  children: [
    {
      path: "photos/june",
      name: "june",
      size: 400,
      type: "directory",
      children: [
        {
          path: "photos/june/windsurf.jpg",
          name: "windsurf.jpg",
          size: 400,
          type: "file",
          extension: ".jpg"
        }
      ]
    },
    {
      path: "photos/january",
      name: "january",
      size: 200,
      type: "directory",
      children: [
        {
          path: "photos/january/ski.png",
          name: "ski.png",
          size: 100,
          type: "file",
          extension: ".png"
        },
        {
          path: "photos/january/snowboard.jpg",
          name: "snowboard.jpg",
          size: 100,
          type: "file",
          extension: ".jpg"
        }
      ]
    }
  ]
}

Пользовательский объект

В противном случае, если вы хотите создать объект дерева каталогов с вашими пользовательскими настройками, посмотрите следующий фрагмент. Живой пример виден в этом коды и коды..

// my-script.js
const fs = require("fs");
const path = require("path");

const isDirectory = filePath => fs.statSync(filePath).isDirectory();
const isFile = filePath => fs.statSync(filePath).isFile();

const getDirectoryDetails = filePath => {
  const dirs = fs.readdirSync(filePath);
  return {
    dirs: dirs.filter(name => isDirectory(path.join(filePath, name))),
    files: dirs.filter(name => isFile(path.join(filePath, name)))
  };
};

const getFilesRecursively = (parentPath, currentFolder) => {
  const currentFolderPath = path.join(parentPath, currentFolder);
  let currentDirectoryDetails = getDirectoryDetails(currentFolderPath);

  const final = {
    current_dir: currentFolder,
    dirs: currentDirectoryDetails.dirs.map(dir =>
      getFilesRecursively(currentFolderPath, dir)
    ),
    files: currentDirectoryDetails.files
  };

  return final;
};

const getAllFiles = relativePath => {
  const fullPath = path.join(__dirname, relativePath);
  const parentDirectoryPath = path.dirname(fullPath);
  const leafDirectory = path.basename(fullPath);

  const allFiles = getFilesRecursively(parentDirectoryPath, leafDirectory);
  return allFiles;
};

module.exports = { getAllFiles };

Тогда вы можете просто сделать:

// another-file.js 

const { getAllFiles } = require("path/to/my-script");

const allFiles = getAllFiles("/path/to/my-directory");
person Mahesh    schedule 11.02.2020

Вот асинхронная рекурсивная версия.

    function ( path, callback){
     // the callback gets ( err, files) where files is an array of file names
     if( typeof callback !== 'function' ) return
     var
      result = []
      , files = [ path.replace( /\/\s*$/, '' ) ]
     function traverseFiles (){
      if( files.length ) {
       var name = files.shift()
       fs.stat(name, function( err, stats){
        if( err ){
         if( err.errno == 34 ) traverseFiles()
    // in case there's broken symbolic links or a bad path
    // skip file instead of sending error
         else callback(err)
        }
        else if ( stats.isDirectory() ) fs.readdir( name, function( err, files2 ){
         if( err ) callback(err)
         else {
          files = files2
           .map( function( file ){ return name + '/' + file } )
           .concat( files )
          traverseFiles()
         }
        })
        else{
         result.push(name)
         traverseFiles()
        }
       })
      }
      else callback( null, result )
     }
     traverseFiles()
    }
person Oggy Transfluxitor Jones    schedule 01.03.2014
comment
Возьмите за привычку ставить точки с запятой в конце ваших утверждений. В противном случае вы не сможете минимизировать код. Тем не менее, спасибо за столь необходимый вклад async. - person user2867288; 08.07.2015
comment
ХАХАХАХА, это не часть спецификации, просто какой-то случайный человек назвал свой предпочтительный стиль линтинга standardjs. Использование точки с запятой является хорошей практикой, особенно в Javascript, для обеспечения ясности кода. В противном случае вы и ваша команда должны запомнить правила автоматическая вставка точки с запятой, и я знаю, по крайней мере, что средний JS-разработчик, в котором я работаю, не так усерден. - person user2867288; 20.02.2019
comment
@ user2867288 Но поскольку ASI существует, мы можем его использовать, не так ли? Я использую eslint и prettier для регулярного форматирования кода при регулярном сохранении, и вставка точки с запятой не является проблемой. - person douira; 18.01.2020

Взял общий подход @ Hunan-Rostomyan, сделал его немного более кратким и добавил excludeDirs аргумент. Было бы тривиально расширить с помощью includeDirs, просто следуйте тому же шаблону:

import * as fs from 'fs';
import * as path from 'path';

function fileList(dir, excludeDirs?) {
    return fs.readdirSync(dir).reduce(function (list, file) {
        const name = path.join(dir, file);
        if (fs.statSync(name).isDirectory()) {
            if (excludeDirs && excludeDirs.length) {
                excludeDirs = excludeDirs.map(d => path.normalize(d));
                const idx = name.indexOf(path.sep);
                const directory = name.slice(0, idx === -1 ? name.length : idx);
                if (excludeDirs.indexOf(directory) !== -1)
                    return list;
            }
            return list.concat(fileList(name, excludeDirs));
        }
        return list.concat([name]);
    }, []);
}

Пример использования:

console.log(fileList('.', ['node_modules', 'typings', 'bower_components']));
person A T    schedule 15.01.2016
comment
У меня есть основная папка: scss, а внутри нее другая папка: themes, но окончательный список дает мне все каталоги, а не только каталоги без исключения каталога, что происходит? - person SalahAdDin; 26.04.2016
comment
Прекрасно работает только с '.' каталог папки, с остальными каталогами не работает. - person SalahAdDin; 26.04.2016

Это TypeScript, необязательно рекурсивный, необязательно с регистрацией ошибок и асинхронным решением. Вы можете указать регулярное выражение для имен файлов, которые хотите найти.

Я использовал fs-extra, потому что это простое улучшение суперсета на fs.

import * as FsExtra from 'fs-extra'

/**
 * Finds files in the folder that match filePattern, optionally passing back errors .
 * If folderDepth isn't specified, only the first level is searched. Otherwise anything up
 * to Infinity is supported.
 *
 * @static
 * @param {string} folder The folder to start in.
 * @param {string} [filePattern='.*'] A regular expression of the files you want to find.
 * @param {(Error[] | undefined)} [errors=undefined]
 * @param {number} [folderDepth=0]
 * @returns {Promise<string[]>}
 * @memberof FileHelper
 */
public static async findFiles(
    folder: string,
    filePattern: string = '.*',
    errors: Error[] | undefined = undefined,
    folderDepth: number = 0
): Promise<string[]> {
    const results: string[] = []

    // Get all files from the folder
    let items = await FsExtra.readdir(folder).catch(error => {
        if (errors) {
            errors.push(error) // Save errors if we wish (e.g. folder perms issues)
        }

        return results
    })

    // Go through to the required depth and no further
    folderDepth = folderDepth - 1

    // Loop through the results, possibly recurse
    for (const item of items) {
        try {
            const fullPath = Path.join(folder, item)

            if (
                FsExtra.statSync(fullPath).isDirectory() &&
                folderDepth > -1)
            ) {
                // Its a folder, recursively get the child folders' files
                results.push(
                    ...(await FileHelper.findFiles(fullPath, filePattern, errors, folderDepth))
                )
            } else {
                // Filter by the file name pattern, if there is one
                if (filePattern === '.*' || item.search(new RegExp(filePattern, 'i')) > -1) {
                    results.push(fullPath)
                }
            }
        } catch (error) {
            if (errors) {
                errors.push(error) // Save errors if we wish
            }
        }
    }

    return results
}
person Paul F. Wood    schedule 18.04.2019

Мои 2 цента, если кто-то:

Просто хотите перечислить имена файлов (без каталогов) из локальной подпапки в своем проекте

  • ✅ Никаких дополнительных зависимостей
  • ✅ 1 функция
  • ✅ Нормализовать путь (Unix против Windows)
const fs = require("fs");
const path = require("path");

/**
 * @param {string} relativeName "resources/foo/goo"
 * @return {string[]}
 */
const listFileNames = (relativeName) => {
  try {
    const folderPath = path.join(process.cwd(), ...relativeName.split("/"));
    return fs
      .readdirSync(folderPath, { withFileTypes: true })
      .filter((dirent) => dirent.isFile())
      .map((dirent) => dirent.name.split(".")[0]);
  } catch (err) {
    // ...
  }
};

README.md
package.json
resources
 |-- countries
    |-- usa.yaml
    |-- japan.yaml
    |-- gb.yaml
    |-- provinces
       |-- .........


listFileNames("resources/countries") #=> ["usa", "japan", "gb"]
person Manu    schedule 20.07.2020
comment
У вас есть проблема, когда path - это имя вашего импортированного require('path'), но затем вы повторно определяете const path внутри функции ... Это действительно сбивает с толку и может привести к ошибкам! - person mesqueeb; 20.09.2020

Внимание: если вы планируете выполнять операции с каждым файлом в каталоге, попробуйте vinyl-fs (который используется gulp, системой потоковой сборки).

person XåpplI'-I0llwlg'I -    schedule 12.06.2014

Это сработает и сохранит результат в файле test.txt, который будет находиться в том же каталоге.

  fs.readdirSync(__dirname).forEach(file => {
    fs.appendFileSync("test.txt", file+"\n", function(err){
    })
})
person Rama    schedule 19.07.2019

Я недавно создал для этого инструмент, который делает именно это ... Он асинхронно извлекает каталог и возвращает список элементов. Вы можете получить каталоги, файлы или и то, и другое, причем папки будут первыми. Вы также можете разбить данные на страницы, если вы не хотите извлекать всю папку.

https://www.npmjs.com/package/fs-browser

Это ссылка, надеюсь, она кому-то поможет!

person stefantigro    schedule 11.04.2020

Я создал модуль узла для автоматизации этой задачи: mddir

использование

узел mddir "../relative/path/"

Для установки: npm install mddir -g

Чтобы сгенерировать уценку для текущего каталога: mddir

Чтобы сгенерировать для любого абсолютного пути: mddir / absolute / path

Чтобы сгенерировать для относительного пути: mddir ~ / Documents / something.

Файл md создается в вашем рабочем каталоге.

В настоящее время игнорирует папки node_modules и .git.

Исправление проблем

Если вы получаете сообщение об ошибке «узел \ r: нет такого файла или каталога», проблема в том, что ваша операционная система использует разные окончания строк, и mddir не может их проанализировать без явной установки стиля окончания строки на Unix. Обычно это влияет на Windows, но также и на некоторые версии Linux. Установка окончаний строк в стиле Unix должна выполняться в глобальной папке bin mddir npm.

Исправлены окончания строк

Получите путь к папке npm bin с помощью:

npm config get prefix

CD в ​​эту папку

варить установить dos2unix

библиотека dos2unix / node_modules / mddir / src / mddir.js

Это преобразует окончания строк в Unix вместо Dos

Затем запустите как обычно: node mddir "../relative/path/".

Пример сгенерированной файловой структуры уценки 'directoryList.md'

    |-- .bowerrc
    |-- .jshintrc
    |-- .jshintrc2
    |-- Gruntfile.js
    |-- README.md
    |-- bower.json
    |-- karma.conf.js
    |-- package.json
    |-- app
        |-- app.js
        |-- db.js
        |-- directoryList.md
        |-- index.html
        |-- mddir.js
        |-- routing.js
        |-- server.js
        |-- _api
            |-- api.groups.js
            |-- api.posts.js
            |-- api.users.js
            |-- api.widgets.js
        |-- _components
            |-- directives
                |-- directives.module.js
                |-- vendor
                    |-- directive.draganddrop.js
            |-- helpers
                |-- helpers.module.js
                |-- proprietary
                    |-- factory.actionDispatcher.js
            |-- services
                |-- services.cardTemplates.js
                |-- services.cards.js
                |-- services.groups.js
                |-- services.posts.js
                |-- services.users.js
                |-- services.widgets.js
        |-- _mocks
            |-- mocks.groups.js
            |-- mocks.posts.js
            |-- mocks.users.js
            |-- mocks.widgets.js
person John Byrne    schedule 28.10.2017

Используйте модуль npm list-contents. Он считывает содержимое и вложенное содержимое данного каталога и возвращает список путей к файлам и папкам.

const list = require('list-contents');

list("./dist",(o)=>{
  if(o.error) throw o.error;
   console.log('Folders: ', o.dirs);
   console.log('Files: ', o.files);
});
person Paweł    schedule 23.07.2018

Обычно я использую: FS-Extra.

const fileNameArray = Fse.readdir('/some/path');

Результат:

[
  "b7c8a93c-45b3-4de8-b9b5-a0bf28fb986e.jpg",
  "daeb1c5b-809f-4434-8fd9-410140789933.jpg"
]
person LondonGuy    schedule 07.07.2020
comment
Если мне нужно прочитать подкаталоги, я хочу сказать рекурсивный, тогда как может быть полезен fs-extra @LondonGuy - person Praveen; 27.05.2021

Если многие из вышеперечисленных вариантов кажутся слишком сложными или нет, то вам нужен другой подход с использованием node -dir - https://github.com/fshost/node-dir

npm install node-dir

Вот простая функция для вывода списка всех файлов .xml, выполняющих поиск в подкаталогах.

import * as nDir from 'node-dir' ;

listXMLs(rootFolderPath) {
    let xmlFiles ;

    nDir.files(rootFolderPath, function(err, items) {
        xmlFiles = items.filter(i => {
            return path.extname(i) === '.xml' ;
        }) ;
        console.log(xmlFiles) ;       
    });
}
person Mauricio Gracia Gutierrez    schedule 14.02.2021