nodejs 通过readdir方法 遍历指定文件夹下所有的文件夹(更新版) 第二种方法会在遍历完成后回调

本文介绍使用Node.js的fs模块遍历指定目录下所有文件和子目录的两种方法。第一种方法直接使用readdir和fs.stat同步遍历,打印出文件和文件夹。第二种方法采用异步迭代,收集所有文件和目录信息,在迭代完成后回调处理,适用于需要在遍历结束后统一处理数据的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过readdir方法 遍历指定文件夹下所有的文件夹

文件结构

在这里插入图片描述

代码

var fs = require('fs');
// 指定是父级文件下的什么的文件夹
var dirfath = 'html1';

readDir(dirfath);

function readDir(dirfather) {
	fs.readdir(dirfather, function(err, data) {
		if (err) {
			console.log('停止迭代');
			return false;
		}
		// 这个data数组中装的是当前文件夹下所有的文件名(包括文件夹)
		data.forEach(function(el, index) {
			// 加上父级访问更深层的文件夹
			fs.stat( `${dirfather}/`+ el, function(errFiletype, dataFile) {
				// 如果触发这个就证明程序错误
				if (errFiletype) {
					console.log('读取文件错误', errFiletype);
					return false;
				}
				
				// 又是文件夹
				if( dataFile.isDirectory()) {
					// 遍历文件夹
					console.log('是文件夹:' + `${dirfather}/`+ el);
					// 迭代
					readDir(`${dirfather}/`+ el);
				} else {
					// 遍历文件
					console.log('是文件: ' + `${dirfather}/`+ el);
				}
			})
			
		})
	})

结果

在这里插入图片描述

第二种方法

  • 第二种方法会在遍历完成后回调

把下面的这个封装到一个文件里面, 然后用CommonJS的方法引用就可以了

下面这个比较好的地方是通过类似查询的方式修改过的, 它可以在迭代完成的时候再将数据送到main函数中进行处理

const fs = require("fs")

let dirArray = [];         // 这个的作用是存储结果
let flieArray = [];         // 这个东西的作用是存储文件
let arrObj = {};
arrObj.dirArr = dirArray;
arrObj.fileArr = flieArray;
let number = 0;            // number的作用是找到迭代结束的位置

/**
 * 
 * @param {*} dir 路径
 * 迭代的函数本身, 它会调用foreach函数
 */
function readDirIter2(dir) {
    // 开始的时候加一
    number++;
    foreach(dir)
}

/**
 * 这个异步的作用是获取到结果
 */
async function getArray() {
    return new Promise((resolve, reject) => {
        let timer1 = setInterval(function() {
            if( number == 0 ) {
                resolve(arrObj)
                clearInterval(timer1)
            }
        }, 1)
    })
}

/**
 * 
 * @param {*} dir 读取文件夹的路径
 * 这个文件的作用是读取路径
 */
async function readDir(dir) {
    return new Promise((resolve, reject) => {
        fs.readdir(dir + "/", (err, data) => {
            if(err) {
                console.log("路径错误")
                console.error(err)
                return;
            }
            resolve(data)
        })
    })
}

/**
 * 
 * @param {} dir 
 * 这个的作用是遍历路径值, 看路径是文件还是文件夹
 * 如果是文件夹则又调用路径读取迭代
 */
async function foreach(dir) {
    let data = await readDir(dir);
    if( data.length == 0 ) {
        // 如果数组长度为0 number减一
        --number;
    }

    data.forEach((el, index, arr) => {
        fs.stat( dir + "/" + el, (err, data) => {
            if( err ) {
                // 这里代变整个代码错了
                console.log("路径错误")
                console.error(err)
                return;
            }

            if(!data.isFile()) {
                dirArray.push(dir + "/" + el);
                readDirIter2(dir + "/" + el)
            }

            if(data.isFile()) {
            	flieArray.push(dir + "/" + el);
            }

            // 如果是文件且是最后一个number减一
            if( arr.length == index + 1 ) {
                --number
            }
            
        })
    })
}

/**
 * 
 * @param {*} dir 要查找的路径
 * 入口函数
 */
async function main(dir) {
    readDirIter2(dir)
    let obj = await getArray();
    return obj;
}

exports.main = main;

使用

let fun = require("./app.js")

fun.main(".").then(res => {
	console.log(res);
});

在这里插入图片描述

这里可以对回调后的数据进行处理
可以在入口函数中对这个东西尽心处理

这样就可以使用了

let fun = require("./test.js")

fun.main(".")

如果不分开这个代码是这样的

分开了也是可以运行的

const fs = require("fs")

let dirArray = [];         // 这个的作用是存储结果
let number = 0;            // number的作用是找到迭代结束的位置


function readDirIter2(dir) {
    // 开始的时候加一
    number++;
    foreach(dir)
    // test().then(res => {
    //     console.log(res)
    // });
}

/**
 * 这个异步的作用是获取到结果
 */
async function getArray() {
    return new Promise((resolve, reject) => {
        let timer1 = setInterval(function() {
            if( number == 0 ) {
                resolve(dirArray)
                clearInterval(timer1)
            }
        }, 1)
    })
}

/**
 * 
 * @param {*} dir 读取文件夹的路径
 * 这个文件的作用是读取路径
 */
async function readDir(dir) {
    return new Promise((resolve, reject) => {
        fs.readdir(dir + "/", (err, data) => {
            if(err) {
                console.log("路径错误")
                console.error(err)
                return;
            }
            resolve(data)
        })
    })
}

/**
 * 
 * @param {} dir 
 * 这个的作用是遍历路径值, 看路径是文件还是文件夹
 * 如果是文件夹则又调用路径读取迭代
 */
async function foreach(dir) {
    let data = await readDir(dir);
    if( data.length == 0 ) {
        // 如果数组长度为0 number减一
        --number;
    }

    data.forEach((el, index, arr) => {
        fs.stat( dir + "/" + el, (err, data) => {
            if( err ) {
                // 这里代变整个代码错了
                console.log("路径错误")
                console.error(err)
                return;
            }

            if(!data.isFile()) {
                dirArray.push(dir + "/" + el);
                readDirIter2(dir + "/" + el)
            }

            // 如果是文件且是最后一个number减一
            if( arr.length == index + 1 ) {
                --number
            }
            
        })
    })
}

/**
 * 入口函数
 */
async function main() {
    readDirIter2(".")
    let arr = await getArray();
    console.log(arr)
}

main();

在这里插入图片描述

由于涉及到服务器文件的遍历,需要使用服务器端的代码。以下是使用Node.js实现服务器文件遍历的示例代码: ```javascript const fs = require('fs'); // 定义遍历函数 function traverseFolder(folderPath) { fs.readdir(folderPath, function(err, files) { if (err) { console.error(err); return; } files.forEach(function(file) { const fullPath = folderPath + '/' + file; fs.stat(fullPath, function(err, stats) { if (err) { console.error(err); return; } if (stats.isDirectory()) { // 如果是文件夹,递归进入 traverseFolder(fullPath); } else { // 如果是文件,可以做相应的处理 console.log(fullPath); } }); }); }); } // 调用遍历函数 traverseFolder('/path/to/your/folder'); ``` 上述代码中,`traverseFolder`函数用于遍历指定路径下的所有文件和文件夹。对于每个文件夹,递归进入;对于每个文件,可以做相应的处理,例如打印路径。 此外,还需要在Node.js中使用HTTP模块搭建一个简单的Web服务器,以便在浏览器中访问文件列表。以下是示例代码: ```javascript const http = require('http'); const fs = require('fs'); const path = require('path'); // 定义遍历函数 function traverseFolder(folderPath, callback) { fs.readdir(folderPath, function(err, files) { if (err) { callback(err); return; } const results = []; files.forEach(function(file) { const fullPath = folderPath + '/' + file; fs.stat(fullPath, function(err, stats) { if (err) { callback(err); return; } const item = { name: file, path: fullPath, isDirectory: stats.isDirectory() }; if (stats.isDirectory()) { // 如果是文件夹,递归进入 traverseFolder(fullPath, function(err, children) { if (err) { callback(err); return; } item.children = children; results.push(item); if (results.length === files.length) { callback(null, results); } }); } else { // 如果是文件,直接添加到结果数组中 results.push(item); if (results.length === files.length) { callback(null, results); } } }); }); }); } // 创建HTTP服务器 const server = http.createServer(function(req, res) { // 获取当前路径 const currentPath = '.' + req.url; // 如果是文件,直接返回文件内容 if (fs.existsSync(currentPath) && fs.statSync(currentPath).isFile()) { fs.readFile(currentPath, function(err, data) { if (err) { res.writeHead(500); res.end(); return; } res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end(data); }); return; } // 如果是文件夹,返回文件列表 traverseFolder(currentPath, function(err, results) { if (err) { res.writeHead(500); res.end(); return; } // 生成HTML代码,展示文件列表 let html = '<ul>'; results.forEach(function(item) { html += '<li>'; if (item.isDirectory) { html += '<a href="' + item.path + '">' + item.name + '</a>'; if (item.children) { html += '<ul>'; item.children.forEach(function(child) { html += '<li><a href="' + child.path + '">' + child.name + '</a></li>'; }); html += '</ul>'; } } else { html += item.name; } html += '</li>'; }); html += '</ul>'; res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(html); }); }); // 启动服务器 server.listen(8080, function() { console.log('Server is listening on port 8080'); }); ``` 上述代码中,`traverseFolder`函数的作用与之前的示例代码相同,但这里将结果包装为一个对象数组,以便在浏览器中进行展示。同时,返回的结果是一个异步回调函数的参数,而非直接输出到控制台。 在HTTP服务器中,首先判断当前请求的路径是否是一个文件,如果是,则直接返回文件内容。否则,调用`traverseFolder`函数获取文件列表,并生成HTML代码,向浏览器输出。需要注意的是,这里使用了`fs.existsSync`和`fs.statSync`函数判断当前路径是否是一个文件,以避免遍历整个文件夹
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值