求教,怎么用Nodejs异步方式计算一个文件夹下总文件数
求教,怎么用Nodejs异步方式计算一个文件夹下总文件数
如果是同步方式,一个递归很容易解决这个问题,异步方式怎么实现?
同步方式代码:
var fs = require('fs');
var getFileNum = function(fileName) {
var num = 0;
var stats = fs.statSync(fileName);
if (stats.isDirectory()) {
var files = fs.readdirSync(fileName);
for ( var i = 0; i < files.length; i++) {
num += getFileNum(fileName + '\\' + files[i]);
}
} else if (stats.isFile()) {
num += 1;
}
return num;
}
var num = getFileNum('E:\\');
console.log(num);
当然可以。为了使用异步方式计算一个文件夹下的总文件数,我们可以利用Node.js的fs.promises
模块来实现。这种方式可以避免阻塞事件循环,从而提高程序的整体性能。
异步版本代码
首先,我们需要将同步的代码转换为基于Promise的异步版本。这可以通过引入fs.promises
模块来实现,该模块提供了与fs
模块相同的方法,但返回的是Promise对象,这样我们就可以使用.then()
或async/await
语法来处理异步操作。
以下是使用async/await
语法的异步代码示例:
const fs = require('fs').promises;
const path = require('path');
const getFileNumAsync = async (dirPath) => {
try {
const files = await fs.readdir(dirPath);
let fileCount = 0;
for (const file of files) {
const filePath = path.join(dirPath, file);
const isDirectory = await fs.stat(filePath);
if (isDirectory.isDirectory()) {
fileCount += await getFileNumAsync(filePath);
} else if (isDirectory.isFile()) {
fileCount++;
}
}
return fileCount;
} catch (error) {
console.error(`Error reading directory: ${error.message}`);
return 0;
}
};
(async () => {
const num = await getFileNumAsync('E:\\');
console.log(`Total number of files: ${num}`);
})();
解释
-
引入模块:
fs.promises
提供了异步版本的文件系统方法。path
模块用于处理和转换文件路径。
-
定义异步函数:
getFileNumAsync
是一个异步函数,它接受一个目录路径作为参数。- 使用
await fs.readdir(dirPath)
来异步读取目录中的所有文件和子目录名。 - 对于每个文件或子目录,使用
await fs.stat(filePath)
来获取其状态信息(是否为文件或目录)。 - 如果是目录,则递归调用
getFileNumAsync
并累加结果。 - 如果是文件,则增加计数器
fileCount
。
-
错误处理:
- 使用
try...catch
结构来捕获并处理可能发生的错误。
- 使用
-
执行函数:
- 使用立即执行的异步函数
(async () => { ... })()
来启动整个过程,并打印最终的结果。
- 使用立即执行的异步函数
这种方法不仅保持了代码的清晰性,还确保了异步操作的高效执行。
var exec = require('child_process').exec;
exec('find * -type f | wc -l', function(error, stdout, stderr) {
console.log(stdout);
})
一楼正解 调用系统命令最省事儿
还是没解决这个问题,只是用系统命令取代的代码实现,如果换个系统,或代码再加点功能,比如说,计算文件夹下所有文件的总行数,这个代码又要全部写了
total=0
cd $1
for dir in `find * -type f`; do
len=`wc -l < $dir`
if [ $? -ne 0 ] ; then
echo "\n \033[32mError: $dir\033[0m\n\n"
else
echo "seraching $dir $len"
total=$(( $total+$len ))
fi
done
echo "Total Lines: $total"
统计行数可以这么写,每个平台都是有shell命令的,JS要做系统层的脚本还真没有bash顺手。
同意楼上的,干这些事用bash才是正路
这么做是简单,但那怎么兼容不同的操作系统?
为了实现异步方式计算文件夹下的总文件数,可以使用 fs.promises
或 fs
模块的回调函数。这里提供一个使用 fs.promises
的示例代码,因为它更加直观和现代。
首先,你需要确保 Node.js 版本支持 fs.promises
(通常需要 >= 10.0.0)。
示例代码
const fs = require('fs').promises;
const path = require('path');
async function getFileNum(dirPath) {
let totalFiles = 0;
const items = await fs.readdir(dirPath);
for (let item of items) {
const fullPath = path.join(dirPath, item);
const stats = await fs.stat(fullPath);
if (stats.isDirectory()) {
totalFiles += await getFileNum(fullPath);
} else if (stats.isFile()) {
totalFiles += 1;
}
}
return totalFiles;
}
(async () => {
try {
const num = await getFileNum('E:\\');
console.log(`Total number of files: ${num}`);
} catch (error) {
console.error("Error:", error.message);
}
})();
解释
-
引入模块:
- 使用
fs.promises
和path
模块。
- 使用
-
定义异步函数
getFileNum
:- 函数接收一个目录路径作为参数。
- 初始化文件计数器
totalFiles
。 - 使用
readdir
异步读取目录中的所有文件和子目录。 - 遍历读取到的每个项目,检查其是否为目录或文件。
- 如果是目录,则递归调用
getFileNum
并累加返回的文件数。 - 如果是文件,则增加文件计数器。
- 最终返回总的文件数量。
-
主程序:
- 将
getFileNum
包装在一个立即执行的异步函数中,以方便使用await
关键字。 - 调用
getFileNum
并输出结果。 - 捕获并处理可能发生的错误。
- 将
这样,你就可以通过异步方式计算文件夹下的总文件数了。