我想使用then()
,如下所示,在我的代码完成了递归文件夹层次结构之后。
一切正常,尤其是
的使用 const fileNames = await fs.promises.readdir(dir);
和
const stat = await fs.promises.stat(thing_path);
但是,递归部分我不知道该如何正确实现
getFolderInfo(start).then((all_data)=>{
console.log('Done recursing the directory');
});
正常工作。
完成文件
const fs = require('fs');
const path = require('path');
// Configure & Initialize
let start = '_t/';
let depth = 1;
let counter = 0;
let total_size = 0;
// Definition
async function recurseFolders(dir, callback) {
const fileNames = await fs.promises.readdir(dir);
const listings = await Promise.all(
fileNames.map(async (thing_name) => {
const thing_path = path.join(dir, thing_name);
const stat = await fs.promises.stat(thing_path);
return {name: thing_name, path: thing_path, size: stat.size, isFolder: stat.isDirectory()};
})
);
listings.forEach(iterate);
function iterate (listing) {
counter++;
total_size += listing.size;
listing.counter = counter;
listing.total_size = total_size;
callback(listing);
if (listing.isFolder) {
recurseFolders(listing.path, callback);
}
}
}
async function getFolderInfo (start) {
await recurseFolders(start, (data) => {
console.log(data);
});
}
getFolderInfo(start).then((all_data)=>{
console.log('Done recursing the directory');
});
答案 0 :(得分:1)
如果将fs工作放到其自己的功能中,则问题可以很好地解决。此函数在给定路径上运行stat
,并为每个条目回答修改后的stat对象...
async function getStats(path) {
const names = await fs.promises.readdir(path);
let promises = names.map(async name => {
const pathName = path.join(path, name)
const stat = await fs.promises.stat(pathName);
return { name: name, path: pathName, size: stat.size, isFolder: stat.isDirectory() };
})
return await Promise.all(promises)
}
现在,只需为给定路径调用getStats,将回调应用于每个结果,然后对包含的目录进行递归或不执行任何操作...
async function recurseFolders(path, callback) {
const stats = await getStats(path)
let promises = stats.map(async stat => {
callback(stat)
return await stat.isFolder ? recurseFolders(stat.path, callback) : Promise.resolve()
})
return await Promise.all(promises)
}
就是这样。
答案 1 :(得分:0)
var fs = require('fs');
var path = require('path');
var getFolderInfo = function (dir, done) {
var results = [];
fs.readdir(dir, function (err, list) {
if (err) return done(err);
var pending = list.length;
if (!pending) return done(null, results);
list.forEach(function (file) {
file = path.resolve(dir, file);
fs.stat(file, function (err, stat) {
if (stat && stat.isDirectory()) {
getFolderInfo(file, function (err, res) {
results = results.concat(res);
if (!--pending) done(null, results);
});
} else {
results.push(file);
if (!--pending) done(null, results);
}
});
});
});
};
getFolderInfo('/home/username', function (err, results) {
if (err) throw err;
console.log(results);
});
答案 2 :(得分:0)
如果您不尝试将文件夹层次结构简化为列表,则可以简化此操作。我对您期望如何使用counter
和total_size
作了一些假设。我也忽略了未使用的depth
参数。
const fs = require('fs');
const path = require('path');
async function recurseFolders(folderPath) {
const fileNames = await fs.promises.readdir(folderPath);
const fileData = await Promise.all(
fileNames.map(async (fileName) => {
const filePath = path.join(folderPath, fileName);
const fileStat = await fs.promises.stat(filePath);
if (fileStat.isDirectory()) {
return recurseFolders(filePath);
}
return {
name: fileName,
path: filePath,
size: fileStat.size,
isFolder: false
};
})
);
const folder = {
name: path.basename(folderPath),
path: folderPath,
files: fileData,
isFolder: true,
count: fileData.length,
size: 0
};
return fileData.reduce((total, file) => {
total.size += file.size;
if (file.isFolder) {
total.count += file.count;
}
return total;
}, folder);
}
recurseFolders('some/path/to/folder').then((file) => {
console.log(file);
}).catch((err) => {
process.exitCode = 1;
console.error(err);
});
此实现将返回如下所示的数据结构:
{
"name": "demo",
"path": "example/path/demo",
"files": [
{
"name": "dir1",
"path": "example/path/demo/dir1",
"files": [
{
"name": "dir2",
"path": "example/path/demo/dir1/dir2",
"files": [
{
"name": "file3.txt",
"path": "example/path/demo/dir1/dir2/file3.txt",
"size": 7412,
"isFolder": false
}
],
"isFolder": true,
"count": 1,
"size": 7412
},
{
"name": "file2.txt",
"path": "example/path/demo/dir1/file2.txt",
"size": 8364,
"isFolder": false
}
],
"isFolder": true,
"count": 3,
"size": 15776
},
{
"name": "file1.txt",
"path": "example/path/demo/file1.txt",
"size": 6870,
"isFolder": false
}
],
"isFolder": true,
"count": 5,
"size": 22646
}