【问题标题】:Get all directories recursive within directory with nodejs使用nodejs递归获取目录中的所有目录
【发布时间】:2020-01-31 10:26:30
【问题描述】:

我想让给定目录中的所有目录同步。

<MyFolder>
    |- Folder1
       |- Folder11
       |- Folder12
    |- Folder2
    |- File1.txt
    |- File2.txt
    |- Folder3
        |- Folder31
        |- Folder32

我希望得到一个数组:

["Folder1/Folder11", "Folder1/Folder12", "Folder2", "Folder3/Folder31", "Folder3/Folder32"]

这是我的代码:

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

function flatten(lists) {
  return lists.reduce((a, b) => a.concat(b), []);
}

function getDirectories(srcpath) {
  return fs.readdirSync(srcpath)
  .map(file => path.join(srcpath, file))
  .filter(path => fs.statSync(path).isDirectory());
}

function getDirectoriesRecursive(srcpath) {
  return [srcpath, ...flatten(getDirectories(srcpath).map(getDirectoriesRecursive))];
}

有人能帮我解决上面的问题吗?

【问题讨论】:

  • 您需要格式化返回数组中的元素,对其进行迭代并对元素进行格式化,并从格式化的元素创建新数组以实现您的结果
  • 函数 getDirectoriesRecursive() 似乎工作得相当好......也许你可以详细说明你出了什么问题?当我运行您的代码时,我得到输出: [ '.\\', 'Folder1', 'Folder1\\Folder11', 'Folder1\\Folder12', 'Folder2', 'Folder3', 'Folder3\\Folder31', '文件夹 3\\文件夹 32' ]

标签: javascript node.js recursion directory path


【解决方案1】:

异步

这是一个高度优化的版本,它使用 Node 的快速 fs.Dirent 对象。这种方法允许您跳过每条路径上昂贵的 fs.existsSyncfs.statSync 调用 -

const { readdir } =
  require ("fs/promises")

const { join } =
  require ("path")

const dirs = async (path = ".") =>
  Promise.all
    ( (await readdir (path, { withFileTypes: true }))
        .map
          ( dirent =>
              dirent .isDirectory ()
                ? dirs (join (path, dirent.name))
                : []
          )
    )
    .then
      ( results =>
          [] .concat (path, ...results)
      )

你这样使用它-

dirs ("MyFolder") .then (console.log, console.error)

同步

我们可以改用同步函数来重写上面的函数-

const { readdirSync } =
  require ("fs")

const { join } =
  require ("path")

const dirsSync = (path = ".") =>
  [].concat
    ( path
    , ...readdirSync (path, { withFileTypes: true })
        .map
          ( dirent =>
              dirent .isDirectory ()
                ? dirsSync (join (path, dirent.name))
                : []
          )
    )

你这样使用它-

console .log (dirsSync ("MyFolder"))

这可以通过使用Array.prototype.flatMap 进一步简化-

const { readdirSync } =
  require ("fs")

const { join } =
  require ("path")

const dirsSync = (path = ".") =>
  [ path
  , ...readdirSync (path, { withFileTypes: true })
      .flatMap
        ( dirent =>
            dirent .isDirectory ()
              ? dirsSync (join (path, dirent.name))
              : []
        )
  ]

【讨论】:

    【解决方案2】:

    你快到了,你只需要避免files(不是目录),所以getDirectoriesRecursive(srcpath)函数递归不会抛出错误。

    这应该是最终的getDirectoriesRecursive代码:

    function getDirectoriesRecursive(srcpath) {
      return [srcpath, ...flatten(getDirectories(srcpath).map((p) => {
        try {
          if (fs.existsSync(path)) {
            if (fs.lstatSync(path).isDirectory()) {
              return getDirectoriesRecursive(path);
            }
          }
        } catch (err) {
          console.error(err)
        }
      }).filter(p => p !== undefined))];
    }
    

    这是a live working Repl Demo 以显示"/opt" 内的所有目录。

    【讨论】:

      猜你喜欢
      • 2017-05-18
      • 2023-03-31
      • 2012-11-23
      • 1970-01-01
      • 2011-09-30
      • 2011-02-04
      • 2011-04-26
      • 1970-01-01
      • 2010-12-31
      相关资源
      最近更新 更多