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


当前回答

我的单行代码:

const fs = require("fs")
const path = 'somePath/'

const filesArray = fs.readdirSync(path).filter(file => fs.lstatSync(path+file).isFile())

其他回答

IMO完成此类任务最方便的方法是使用glob工具。这是node.js的glob包

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文件

var globby = require('globby');

const paths = await globby("**/*.xml");  

下面是一个仅使用本机fs和路径模块的简单解决方案:

// 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.readder):

// 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"...
});

不同之处在于节点在执行IO时如何阻塞。考虑到上面的API是相同的,您可以只使用异步版本来确保最大性能。

然而,使用同步版本有一个优点。在遍历完成后立即执行一些代码更容易,就像在遍历后的下一条语句中一样。对于异步版本,您需要一些额外的方法来知道何时完成。也许首先创建所有路径的映射,然后枚举它们。对于简单的build/util脚本(与高性能web服务器相比),您可以使用同步版本而不会造成任何损坏。

这是一个异步递归版本。

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

获取排序的文件名。您可以基于特定扩展名(如“.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();
}

使用flatMap:

function getFiles(dir) {
  return fs.readdirSync(dir).flatMap((item) => {
    const path = `${dir}/${item}`;
    if (fs.statSync(path).isDirectory()) {
      return getFiles(path);
    }

    return path;
  });
}

给定以下目录:

dist
├── 404.html
├── app-AHOLRMYQ.js
├── img
│   ├── demo.gif
│   └── start.png
├── index.html
└── sw.js

用法:

getFiles("dist")

输出:

[
  'dist/404.html',
  'dist/app-AHOLRMYQ.js',
  'dist/img/demo.gif',
  'dist/img/start.png',
  'dist/index.html'
]