Как получить список имен всех файлов, присутствующих в каталоге в Node.js? - PullRequest
794 голосов
/ 28 апреля 2010

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

Ответы [ 20 ]

6 голосов
/ 21 февраля 2018

Получить 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();
}
4 голосов
/ 02 марта 2014

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

    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()
    }
3 голосов
/ 27 января 2019

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

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];
    }, []);

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

3 голосов
/ 15 января 2016

Взял общий подход @ Унаня-Ростомяна, сделал его немного более кратким и добавил 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']));
1 голос
/ 16 февраля 2019

Вы также можете захотеть сделать это рекурсивно.

Для этого есть модуль NPM:

нпм дри

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

Вот код:

const dree = require('dree');

const fileNames = [];
const fileCb = function(file) {
    fileNames.push(file.name);
}

dree.scan('path-to-directory', { extensions: [ 'html', 'js' ] }, fileCb);

console.log(fileNames); // All the html and js files inside the given folder and its subfolders
0 голосов
/ 18 апреля 2019

Это 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
}
0 голосов
/ 23 июля 2018

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

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

list("./dist",(o)=>{
  if(o.error) throw o.error;
   console.log('Folders: ', o.dirs);
   console.log('Files: ', o.files);
});
0 голосов
/ 28 октября 2017

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

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

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

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

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

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

Для создания относительного пути: mddir ~ / Documents / what.

Файл md генерируется в вашем рабочем каталоге.

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

Устранение неполадок

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

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

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

npm config get prefix

Cd в эту папку

brew install dos2unix

dos2unix lib / 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
0 голосов
/ 01 апреля 2014
function getFilesRecursiveSync(dir, fileList, optionalFilterFunction) {
    if (!fileList) {
        grunt.log.error("Variable 'fileList' is undefined or NULL.");
        return;
    }
    var files = fs.readdirSync(dir);
    for (var i in files) {
        if (!files.hasOwnProperty(i)) continue;
        var name = dir + '/' + files[i];
        if (fs.statSync(name).isDirectory()) {
            getFilesRecursiveSync(name, fileList, optionalFilterFunction);
        } else {
            if (optionalFilterFunction && optionalFilterFunction(name) !== true)
                continue;
            fileList.push(name);
        }
    }
}
0 голосов
/ 12 июня 2014

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

...