关于使用fs.readdir进行异步目录搜索有什么想法吗?我意识到我们可以引入递归,并调用read目录函数来读取下一个目录,但我有点担心它不是异步的…
什么好主意吗?我已经看了node-walk,它很棒,但它不能像readdir那样只给我数组中的文件。虽然
寻找这样的输出…
['file1.txt', 'file2.txt', 'dir/file3.txt']
关于使用fs.readdir进行异步目录搜索有什么想法吗?我意识到我们可以引入递归,并调用read目录函数来读取下一个目录,但我有点担心它不是异步的…
什么好主意吗?我已经看了node-walk,它很棒,但它不能像readdir那样只给我数组中的文件。虽然
寻找这样的输出…
['file1.txt', 'file2.txt', 'dir/file3.txt']
当前回答
香草ES6 +异步/等待+小和可读
我没有在这篇文章中找到我想要的答案;在不同的答案中有一些相似的元素,但我只想要一些简单易读的东西。
为了防止它在未来帮助到任何人(比如几个月后的我自己),这就是我最终使用的:
const { readdir } = require('fs/promises');
const { join } = require('path');
const readdirRecursive = async dir => {
const files = await readdir( dir, { withFileTypes: true } );
const paths = files.map( async file => {
const path = join( dir, file.name );
if ( file.isDirectory() ) return await readdirRecursive( path );
return path;
} );
return ( await Promise.all( paths ) ).flat( Infinity );
}
module.exports = {
readdirRecursive,
}
其他回答
有一个名为cup-readdir的新模块,可以快速递归地搜索目录。它使用异步承诺,在处理深层目录结构时性能优于许多流行的模块。
它可以返回数组中的所有文件,并根据它们的属性对它们进行排序,但缺乏文件过滤和进入符号链接目录等功能。这对于只想从目录中获取每个文件的大型项目非常有用。这里是他们项目主页的链接。
还有一种方法。我把它放在这里。也许将来它会对某人有用。
const fs = require("fs");
const { promisify } = require("util");
const p = require("path");
const readdir = promisify(fs.readdir);
async function getFiles(path) {
try {
const entries = await readdir(path, { withFileTypes: true });
const files = entries
.filter((file) => !file.isDirectory())
.map((file) => ({
path: `${path}/${file.name}`,
ext: p.extname(`${path}/${file.name}`),
pathDir: path,
}));
const folders = entries.filter((folder) => folder.isDirectory());
for (const folder of folders) {
files.push(...(await getFiles(`${path}/${folder.name}`)));
}
return files;
} catch (error) {
return error;
}
}
用法:
getFiles(rootFolderPath)
.then()
.catch()
我建议使用node-glob来完成这个任务。
var glob = require( 'glob' );
glob( 'dirname/**/*.js', function( err, files ) {
console.log( files );
});
查看final-fs库。它提供了一个readdirRecursive函数:
ffs.readdirRecursive(dirPath, true, 'my/initial/path')
.then(function (files) {
// in the `files` variable you've got all the files
})
.otherwise(function (err) {
// something went wrong
});
为了好玩,这里有一个基于流的版本,它与highland.js streams库一起工作。作者之一是维克多·伍。
###
directory >---m------> dirFilesStream >---------o----> out
| |
| |
+--------< returnPipe <-----------+
legend: (m)erge (o)bserve
+ directory has the initial file
+ dirListStream does a directory listing
+ out prints out the full path of the file
+ returnPipe runs stat and filters on directories
###
_ = require('highland')
fs = require('fs')
fsPath = require('path')
directory = _(['someDirectory'])
mergePoint = _()
dirFilesStream = mergePoint.merge().flatMap((parentPath) ->
_.wrapCallback(fs.readdir)(parentPath).sequence().map (path) ->
fsPath.join parentPath, path
)
out = dirFilesStream
# Create the return pipe
returnPipe = dirFilesStream.observe().flatFilter((path) ->
_.wrapCallback(fs.stat)(path).map (v) ->
v.isDirectory()
)
# Connect up the merge point now that we have all of our streams.
mergePoint.write directory
mergePoint.write returnPipe
mergePoint.end()
# Release backpressure. This will print files as they are discovered
out.each H.log
# Another way would be to queue them all up and then print them all out at once.
# out.toArray((files)-> console.log(files))