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


当前回答

非递归版本

您并没有说要递归地执行,所以我假设您只需要目录的直接子级。

示例代码:

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

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

其他回答

如果有人:

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

✅ 无其他依赖项✅ 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"]

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

采用@湖南罗斯托米扬的一般方法,使其更加简洁,并添加了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']));

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

开箱即用

如果您想要一个具有开箱即用的目录结构的对象,我强烈建议您检查目录树。

假设你有这样的结构:

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