代码之家  ›  专栏  ›  技术社区  ›  resopollution

如何获得Node.js目录中所有文件的名称列表?

  •  737
  • resopollution  · 技术社区  · 16 年前

    我正在尝试使用Node.js获取目录中所有文件的名称列表。我希望输出是一个文件名数组。我该怎么做?

    19 回复  |  直到 9 年前
        1
  •  1663
  •   mjk Nokhaiz Khalid    5 年前

    你可以用 fs.readdir fs.readdirSync 方法。 fs 包含在Node.js内核中,因此无需安装任何东西。

    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);
    });
    

    第二个是同步的,它将返回文件名数组,但它将停止进一步执行代码,直到读取过程结束。

        2
  •  237
  •   Mauricio Gracia Gutierrez    5 年前

    IMO执行此类任务最方便的方法是使用 glob 工具。这里有一个 glob package 对于node.js。与一起安装

    npm install glob
    

    然后使用通配符匹配文件名(示例取自包的 website )

    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");  
    
        3
  •  186
  •   Matt Fletcher    11 年前

    不过,上面的答案不会对目录执行递归搜索。下面是我所做的递归搜索(使用 node-walk : 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);
    });
    
        4
  •  106
  •   ANURAG Vaibhav Tito100    5 年前

    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'))
    
        5
  •  71
  •   Ali    10 年前

    这里有一个只使用本机的简单解决方案 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"...
    });
    

        6
  •  66
  •   bnp887    7 年前

    从节点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']
    

    Docs for the fs.Dirent class

        7
  •  27
  •   Evan Carroll    10 年前

    与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 ) }
    };
    

    递归列表更新

    一些用户指定希望看到一个递归列表(虽然不在问题中)。。。使用 fs-promise 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));
    
        8
  •  20
  •   Hunan Rostomyan    10 年前

    依赖关系。

    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

        9
  •  20
  •   Tyler Liu    7 年前

    非递归版本

    你没有说你想递归地做它,所以我假设你只需要目录的直接子目录。

    const fs = require('fs');
    const path = require('path');
    
    fs.readdirSync('your-directory-path')
      .filter((file) => fs.lstatSync(path.join(folder, file)).isFile());
    
        10
  •  16
  •   KyleMit Steven Vachon    5 年前

    从你的问题来看,我假设你不需要目录名,只需要文件。

    目录结构示例

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

    Walk 功能

    Justin Maier 在里面 this gist

    如果你愿意的话 只是一个数组 使用的文件路径 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"
    ];
    
        11
  •  14
  •   Josh    7 年前

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

    它的工作对我很好

        12
  •  13
  •   Eduardo Cuomo Sajjad Ali Khan    9 年前

    加载 fs :

    const fs = require('fs');
    

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

    读取文件 :

    var files = fs.readdirSync('./dir');
    
        13
  •  9
  •   Yas    8 年前

    得到 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();
    }
    
        14
  •  6
  •   a.barbieri    6 年前

    开箱即用

    具有目录结构的对象 directory-tree .

    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"
            }
          ]
        }
      ]
    }
    

    否则,如果要创建 具有自定义设置的目录树对象 请看下面的代码片段。一个活生生的例子可以在这个网站上看到 codesandbox .

    // 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");
    
        15
  •  5
  •   Oggy Transfluxitor Jones    12 年前

    这是一个异步递归版本。

        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()
        }
    
        16
  •  5
  •   A T    10 年前

    采用了@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']));
    
        17
  •  5
  •   Paul F. Wood kelloti    7 年前

    我曾经 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
    }
    
        18
  •  5
  •   Manu Artero Rajeev Dutta    5 年前

    只想列出项目中本地子文件夹中的文件名(不包括目录)

    • 无其他依赖项
    • 规范化路径(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"]
    
        19
  •  1
  •   XåpplI'-I0llwlg'I -    12 年前

    只是提醒一下:如果您计划对目录中的每个文件执行操作,请尝试 vinyl-fs (用于 gulp

        20
  •  1
  •   Rama    7 年前

    这将工作并将结果存储在test.txt文件中,该文件将出现在同一目录中

      fs.readdirSync(__dirname).forEach(file => {
        fs.appendFileSync("test.txt", file+"\n", function(err){
        })
    })
    
        21
  •  1
  •   stefantigro    6 年前

    我最近为这个做了一个工具。。。它异步获取一个目录并返回一个项目列表。您可以获取目录、文件或两者,文件夹是第一位的。如果不想获取整个文件夹,也可以对数据进行分页。

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

    这是链接,希望它能帮助别人!

        22
  •  0
  •   John Byrne    8 年前

    我制作了一个节点模块来自动化此任务: mddir

    安装:npm install mddir-g

    为当前目录生成标记:mddir

    为相对路径生成:mddir~/Documents/whatever。

    md文件在您的工作目录中生成。

    当前忽略node\u模块和.git文件夹。

    故障排除

    线条端点固定

    npm config get prefix

    brew安装dos2unix

    这会将行尾转换为Unix而不是Dos

    示例生成的标记文件结构“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
    
        23
  •  0
  •   Paweł    8 年前

    使用 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);
    });
    
        24
  •  0
  •   LondonGuy    6 年前

    我通常使用: FS-Extra .

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

    结果:

    [
      "b7c8a93c-45b3-4de8-b9b5-a0bf28fb986e.jpg",
      "daeb1c5b-809f-4434-8fd9-410140789933.jpg"
    ]
    
        25
  •  0
  •   Mauricio Gracia Gutierrez    5 年前

    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) ;       
        });
    }
    
        26
  •  -1
  •   Francois    12 年前
    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);
            }
        }
    }
    
    推荐文章