Node.js 如何列出一个目录下的所有文件?
Node.js 列目录用 fs.readdir:回调版、Promise 版(fs.promises.readdir)、同步版(readdirSync)任选。加 withFileTypes 可区分文件与目录,递归遍历需自行实现或用第三方库。本文给出完整写法。
**用 fs.readdir 系列方法。**三种风格任选:
回调版
const fs = require('fs');
fs.readdir('/path/to/dir', (err, files) => {
if (err) {
console.error('读取目录失败:', err);
return;
}
files.forEach(file => console.log(file));
});
Promise 版(推荐)
const fs = require('fs').promises;
const files = await fs.readdir('/path/to/dir');
console.log(files); // ['a.txt', 'subdir', 'b.js', ...]
同步版(脚本场景)
const fs = require('fs');
const files = fs.readdirSync('/path/to/dir');
区分文件和目录
readdir 只返回名字。加 withFileTypes: true 拿到类型信息:
const entries = await fs.readdir('/path/to/dir', { withFileTypes: true });
for (const e of entries) {
if (e.isFile()) console.log('文件:', e.name);
if (e.isDirectory()) console.log('目录:', e.name);
}
只想要文件(含过滤扩展名)
const files = (await fs.readdir(dir, { withFileTypes: true }))
.filter(e => e.isFile() && e.name.endsWith('.js'))
.map(e => e.name);
递归遍历子目录
readdir 不递归。简单递归实现:
const path = require('path');
async function walk(dir) {
const entries = await fs.readdir(dir, { withFileTypes: true });
const files = [];
for (const e of entries) {
const full = path.join(dir, e.name);
if (e.isDirectory()) files.push(...await walk(full));
else files.push(full);
}
return files;
}
复杂匹配(glob 模式)直接用 glob 包更省事。
常见问题(FAQ)
Q:readdir 返回的顺序是什么?
操作系统返回的顺序,不保证排序。需要排序自己加 .sort()。
Q:报 ENOENT: no such file or directory?
路径不存在或拼错。用绝对路径或 path.join(__dirname, ...) 避免相对路径因启动目录不同而漂移。
Q:目录里文件几十万,readdir 会卡吗?
readdir 一次性返回全部名字,超大目录会占用内存。Node 20+ 可用 fs.opendir 做迭代式读取。