node.js - 使用 node js 中的 Promise 递归目录列表
问题描述
我想递归地列出目录并使用node.js中的 Promise读取其中的文件。有人可以帮我解决这个问题吗?
解决方案
鉴于此目录结构:
.
├── dirtest
│ ├── bar.txt
│ └── foo
│ └── foo.txt
└── index.js
你有几种方法可以做到这一点。让我们考虑最容易使用async
/进行布局await
,代码中的注释:
const fs = require("fs");
const path = require("path");
const util = require("util");
// Promisify the fs functions we will use (or use require("fs").promises)
const astat = util.promisify(fs.stat);
const areaddir = util.promisify(fs.readdir);
/**
* Get a list of all files in a directory
* @param {String} dir The directory to inventory
* @returns {Array} Array of files
*/
async function getFiles(dir) {
// Get this directory's contents
const files = await areaddir(dir);
// Wait on all the files of the directory
return Promise.all(files
// Prepend the directory this file belongs to
.map(f => path.join(dir, f))
// Iterate the files and see if we need to recurse by type
.map(async f => {
// See what type of file this is
const stats = await astat(f);
// Recurse if it is a directory, otherwise return the filepath
return stats.isDirectory() ? getFiles(f) : f;
}));
}
getFiles(".")
.then(files => JSON.stringify(files, null, 4))
.then(console.log)
.catch(console.error);
这将生成一个嵌套的文件数组,其中包含前面的路径:
[
[
"dirtest/bar.txt",
[
"dirtest/foo/foo.txt"
]
],
"index.js"
]
然后,您可以通过从以下问题中提取来扩充它以获得一个扁平的文件列表:Merge/flatten an array of arrays in JavaScript? :
/**
* Flatten an arbitrarrily deep Array of Arrays to a single Array
* @param {Array} arr Array of Arrays to flatten
* @returns {Array} The flattened Array
*/
function flatten(arr) {
return arr.reduce((flat, toFlatten) => flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten), []);
}
/*
* Same code from above snippet
*/
getFiles(".")
.then(flatten)
.then(files => JSON.stringify(files, null, 4))
.then(console.log)
.catch(console.error);
产生:
[
"dirtest/bar.txt",
"dirtest/foo/foo.txt",
"index.js"
]
推荐阅读
- java - 我的应用程序在我启动和启动时崩溃了?
- ignite - Apache Ignite org.apache.ignite.IgniteCheckedException:握手消息无效
- python - jupyter notebook/lab终端python版
- browser - 如何通过将一些参数传递到 URL 来打开新选项卡
- gcc - 如何在 Catalina 上安装 gcc 7.4
- reactjs - 如何在 componentDidMount 中使用通过 Redux 获取的值
- docker - 如何在使用 Azure DevOps REST API 创建构建定义时提供管道参数?
- c# - 在 linq 查询中包含 where 条件
- javascript - 用户访问页面时如何动态缩放整个 ASP.Net MVC 应用程序
- php - 我如何/真的/删除 PHP 中的文件?