gpt4 book ai didi

javascript - 使用 Node FS 查找文件数量并获取总行数

转载 作者:太空宇宙 更新时间:2023-11-04 00:29:53 25 4
gpt4 key购买 nike

我正在构建一个 Node 脚本,异步输出目录的文件计数和行计数;但是,我在其异步控制流方面遇到了麻烦。

// Import Dependencies
const fs = require('fs');

const get_dir_line_count = (dir) => {
let output = { file_count: 0, file_line: 0, path: '' };
new Promise( (resolve, reject) => {
fs.readdir(dir, (err, dir_contents) => {
resolve(dir_contents);
});
}).then( (promise_contents) => {
Promise.all(promise_contents.map( (file) => {
const file_path = dir + '/' + file;
return new Promise( (resolve, reject) => {
fs.stat(file_path, (err, stat) => {
if(err || file[0] === '.') return err;
if(stat.isDirectory() && file !== 'node_modules'){
get_dir_line_count(file_path);
}
else if(stat.isFile()){
promise_line_count(file_path)
.then( (line_count) => {
output.path = dir;
output.file_line += line_count;
output.file_count++;
resolve(output);
});
};
});
}).then( (resolved_output) => {
console.log(resolved_output)
return resolved_output;
});
}));
});

};

const promise_line_count = (pathToFile) => {
let line_count = 0;
return new Promise( (resolve, reject) => {
fs.createReadStream(pathToFile)
.on("data", (buffer) => {
buffer.forEach( (chunk) => {
if(chunk === 10) line_count++;
});
}).on("end", () => {
resolve(line_count);
});
});
};

const directory = process.argv[2];
get_dir_line_count('./../' + directory);

我的目的是递归地遍历输出 Promise.all 数组的目录。每个数组都是目录计算数据的集合。但是,我在 Promise.all 上遇到异步控制流问题。如果有人可以提供反馈,那将会很有帮助。

输出:

项目 = 5 个文件,50 行

Project/src = 10 个文件,60 行

Project/apple = 20 个文件,200 行

...等等

最佳答案

一个问题是您没有从 get_dir_line_count 函数本身返回任何内容:

const get_dir_line_count = (dir) => {
let output = { file_count: 0, file_line: 0, path: '' };
new Promise( (resolve, reject) => {
// ^---- missing a return statement

另一个问题是您忘记从 Promise.all 返回结果,以便正确构建链:

// ...
}).then( (promise_contents) => {
Promise.all(promise_contents.map( (file) => {
// ^---- missing a return

您还忘记返回(或解析)对 get_dir_line_count 的递归调用:

if(err || file[0] === '.') return err;
if(stat.isDirectory() && file !== 'node_modules'){
get_dir_line_count(file_path);
// ^--- missing a return statement or resolve statement
}

最后,由于您从 get_dir_line_count 返回输出对象,因此您可以通过添加 then 并将结果传递到 console.log 来检查事情是否正常:

const directory = process.argv[2];
get_dir_line_count('./../' + directory).then(console.log) // <-- get the output object and the log it
<小时/>

就处理一般异步代码的复杂性而言,清理控制流可以做的主要事情是将各个逻辑提取到单独的函数中。

您可以在下面找到一种方法的代码示例以及嵌入的注释(我还保留了带下划线的命名首选项):

const fs = require('fs');
const path = require('path');

// resolves with the file names within the given directory
function get_file_names(dir) {
return new Promise((resolve, reject) => {
fs.readdir(dir, (err, fileNames) => {
if (err) return reject(err);
resolve(fileNames);
});
});
}

// resolves with an object containing the type ('file' or 'dir') for the given file path and the file path itself: { file_path, type }
function get_path_and_type(file_path) {
return new Promise((resolve, reject) => {
fs.stat(file_path, (err, stat) => {
if (err) return reject(err);
if (!stat.isDirectory() && !stat.isFile()) reject('Invalid Type');
const type = stat.isDirectory() ? 'dir' : 'file';
resolve({
file_path,
type
});
});
});
}

// same as before, counts lines for the given file path
function count_lines(file_path) {
return new Promise((resolve, reject) => {
let lineCount = 0;
fs.createReadStream(file_path)
.on("data", (buffer) => {
buffer.forEach((chunk) => {
if (chunk === 10) lineCount++;
});
}).on("end", () => {
resolve(lineCount);
}).on("error", reject);
});
};

function get_dir_line_count(dir) {

const output = {
file_count: 0,
file_lines: 0,
path: dir
};

// get all filenames in the given directory
return get_file_names(dir)
// filter all file names that start with a '.' or include the string 'node_modules'
.then((names) =>
names.filter((name) =>
!name.startsWith('.') && !name.includes('node_modules')
)
)
// map every file name into a promise that resolves with the type for that file name within the given dir
.then((names) =>
names.map((name) =>
get_path_and_type(path.join(dir, name))
.catch(console.warn) // log invalid typed files if necessary
)
).then((paths_and_types_promises) =>
Promise.all(paths_and_types_promises.map((promise) =>
promise.then(({
file_path,
type
}) => {
if (type === 'dir') {
// if current file path corresponds to a directory
// recursive count its files and lines and add it to the overall output
return get_dir_line_count(file_path)
.then((recursive_output) => {
output.file_count += recursive_output.file_count;
output.file_lines += recursive_output.file_count;
});
} else {
// count the lines for the current file path and then update the overall output
return count_lines(file_path)
.then((file_lines) => {
output.file_lines += file_lines;
output.file_count += 1;
})
}
})
))
// this last chain makes sure we wait for the promise to resolve
// and populate the output object before resolving with it
).then(() => output);
}

get_dir_line_count(process.argv[2])
.then(console.log);

关于javascript - 使用 Node FS 查找文件数量并获取总行数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41372392/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com