关于使用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']
当前回答
我最近编写了这个代码,并认为在这里分享它是有意义的。代码使用了异步库。
var fs = require('fs');
var async = require('async');
var scan = function(dir, suffix, callback) {
fs.readdir(dir, function(err, files) {
var returnFiles = [];
async.each(files, function(file, next) {
var filePath = dir + '/' + file;
fs.stat(filePath, function(err, stat) {
if (err) {
return next(err);
}
if (stat.isDirectory()) {
scan(filePath, suffix, function(err, results) {
if (err) {
return next(err);
}
returnFiles = returnFiles.concat(results);
next();
})
}
else if (stat.isFile()) {
if (file.indexOf(suffix, file.length - suffix.length) !== -1) {
returnFiles.push(filePath);
}
next();
}
});
}, function(err) {
callback(err, returnFiles);
});
});
};
你可以这样使用它:
scan('/some/dir', '.ext', function(err, files) {
// Do something with files that ends in '.ext'.
console.log(files);
});
其他回答
递归-readdir模块具有此功能。
另一个很好的npm包是glob。
npm公司
它非常强大,应该能满足你所有的递归需求。
编辑:
实际上我对glob不是很满意,所以我创建了readdirp。
我非常有信心,它的API使得递归地查找文件和目录以及应用特定的过滤器非常容易。
阅读它的文档,以更好地了解它的功能和安装方式:
NPM安装readdirp
只是简单的散步
let pending = [baseFolderPath]
function walk () {
pending.shift();
// do stuffs width pending[0] and change pending items
if (pending[0]) walk(pending[0])
}
walk(pending[0])
这是一个简单的同步递归解决方案
const fs = require('fs')
const getFiles = path => {
const files = []
for (const file of fs.readdirSync(path)) {
const fullPath = path + '/' + file
if(fs.lstatSync(fullPath).isDirectory())
getFiles(fullPath).forEach(x => files.push(file + '/' + x))
else files.push(file)
}
return files
}
用法:
const files = getFiles(process.cwd())
console.log(files)
您可以异步地编写它,但是没有必要。只需确保输入目录存在并且可以访问。
下面是一个获得所有文件包括子目录的递归方法。
const FileSystem = require("fs");
const Path = require("path");
//...
function getFiles(directory) {
directory = Path.normalize(directory);
let files = FileSystem.readdirSync(directory).map((file) => directory + Path.sep + file);
files.forEach((file, index) => {
if (FileSystem.statSync(file).isDirectory()) {
Array.prototype.splice.apply(files, [index, 1].concat(getFiles(file)));
}
});
return files;
}