Node.js 递归列出文件的完整路径
Node.js recursively list full path of files
大家晚安。我可能在使用一些简单的递归函数时遇到了麻烦。问题是递归地列出给定文件夹及其子文件夹中的所有文件。
目前,我已经设法使用一个简单的函数列出目录中的文件:
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的初学者,我最终决定向你们寻求帮助。
只需添加一个递归调用即可:
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);
}
});
}
以这种方式使用 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
模块中的异步函数,因为这样可以防止程序在磁盘读取时间过长或网络延迟时挂起。正如其他问答
中所展示的那样,展开可以很好地处理异步
- Recursion call async func with promises gets Possible Unhandled Promise Rejection
大家晚安。我可能在使用一些简单的递归函数时遇到了麻烦。问题是递归地列出给定文件夹及其子文件夹中的所有文件。
目前,我已经设法使用一个简单的函数列出目录中的文件:
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的初学者,我最终决定向你们寻求帮助。
只需添加一个递归调用即可:
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);
}
});
}
以这种方式使用 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
模块中的异步函数,因为这样可以防止程序在磁盘读取时间过长或网络延迟时挂起。正如其他问答
- Recursion call async func with promises gets Possible Unhandled Promise Rejection