【问题标题】:Node.js recursively list full path of filesNode.js 递归列出文件的完整路径
【发布时间】:2020-06-23 22:19:58
【问题描述】:

大家晚安。我可能遇到了一些简单的递归函数的问题。问题是递归列出给定文件夹及其子文件夹中的所有文件。

目前,我已经设法使用一个简单的函数列出目录中的文件:

fs.readdirSync(copyFrom).forEach((file) => {
  let fullPath = path.join(copyFrom, file);

  if (fs.lstatSync(fullPath).isDirectory()) {
    console.log(fullPath);
  } else {
    console.log(fullPath);
  }
});

我已经尝试了各种方法,例如do{} ... while(),但我无法做到正确。由于我是javascript的初学者,我终于决定向你们寻求帮助。

【问题讨论】:

标签: javascript node.js recursion filesystems electron


【解决方案1】:

只需添加一个递归调用即可完成:

 function traverseDir(dir) {
   fs.readdirSync(dir).forEach(file => {
     let fullPath = path.join(dir, file);
     if (fs.lstatSync(fullPath).isDirectory()) {
        console.log(fullPath);
        traverseDir(fullPath);
      } else {
        console.log(fullPath);
      }  
   });
 }

【讨论】:

  • 谢谢,它似乎可以解决问题。但是,执行该函数时我没有任何控制台消息...我一定错过了什么。
  • @YouDeserveThat,也许是个愚蠢的问题,但您实际上是在调用该函数而不只是定义它吗?
  • 嗯。愚蠢的问题通常对初学者有帮助:D。谢谢@FissureKing!
  • @YouDeserveThat 只需像这样调用函数:traverseDir(copyFrom);。另外,如果它解决了您的问题,请接受答案:D
  • 别忘了导入路径var path = require('path');
【解决方案2】:

以这种方式使用console.log 可以显示路径,这很好,但是如果您想对路径做一些更有意义的事情怎么办?例如,也许您想将它们全部收集到一个数组中并将它们传递给其他地方处理......

从种子状态开始并在状态更改时扩展一系列值的过程称为unfold

const { join } =
  require ('path')

const { readdirSync, statSync } =
  require ('fs')

const unfold = (f, initState) =>
  f ( (value, nextState) => [ value, ...unfold (f, nextState) ]
    , () => []
    , initState
    )

const None =
  Symbol ()

const relativePaths = (path = '.') =>
  readdirSync (path) .map (p => join (path, p))

const traverseDir = (dir) =>
  unfold
    ( (next, done, [ path = None, ...rest ]) =>
        path === None
          ? done ()
          : next ( path
                 , statSync (path) .isDirectory ()
                     ? relativePaths (path) .concat (rest)
                     : rest
                 )
    , relativePaths (dir)
    )

console.log (traverseDir ('.'))
// [ a, a/1, a/1/1, a/2, a/2/1, a/2/2, b, b/1, ... ]

如果这是您第一次看到这样的程序,unfold 会感到非常不知所措。下面是unfold 的简化示例,用于生成小写alphabet 的数组

const unfold = (f, init) =>
  f ( (x, next) => [ x, ...unfold (f, next) ]
    , () => []
    , init
    )

const nextLetter = c =>
  String.fromCharCode (c.charCodeAt (0) + 1)

const alphabet =
  unfold
    ( (next, done, c) =>
        c > 'z'
          ? done ()
          : next ( c              // value to add to output
                 , nextLetter (c) // next state
                 )
    , 'a' // initial state
    )

console.log (alphabet)
// [ a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z ]

如果您仍然卡住,我在这里演示的技术将在类似问题的答案中得到更详细的解释

一般来说,最好使用fs 模块中的异步函数,因为这样可以防止程序在磁盘读取时间过长或网络延迟的情况下挂起。正如其他问答中所展示的那样,展开与异步配合得很好

【讨论】:

  • 感谢您提供非常详细的anwser,我明天试试:)
  • @YouDeserve 那是我的荣幸。我最近了解了anamorphisms,现在到处都能看到它们的用例!如果您有任何问题,请告诉我,我很乐意为您提供帮助:D
猜你喜欢
  • 1970-01-01
  • 2019-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-27
  • 1970-01-01
  • 2016-02-19
相关资源
最近更新 更多