getDir:function(cb){
var path=node_path.join(__dirname,dir_path)
var over=[];
function forDir(path){
var fi=fs.readdir(path,function(err,files){
if(err){
return false;
}
async.map(files,function(e,cb){
var paths=node_path.join(path,e)
fs.stat(paths,function(err,file){
if(file.isDirectory()){
cb(null,paths)
}else{
over.push(paths)
}
})
},function(err,results){
results.forEach(function(e,i){
forDir(e)
})
})
})
}
forDir(path)
var len=over.length
var len_one=null;
var se=false;
var timer=setInterval(function(){
if(len_one==len){
clearInterval(timer)
console.log(over)
}
if(se){
len_one=over.length
se=false
}else{
len=over.length
se=true
}
},500)
}
如何判断递归循环完毕? 上面的代码是获取不到最后一次循环的 所以就不知道获取目录什么时候完成
//获取目录下的所有子目录信息
var node_path=require('path');
var fs=require('fs');
//模拟async.map的执行
function myMap(arrayData,call,resultCallback){
var p=arrayData;
var finalResultData=[];
var intercall=function(error,resultData){
watchLength--;
finalResultData.push(resultData);
if(watchLength==0){
resultCallback(null,finalResultData);
}
};
var watchLength=p.length;
for(var i=0;i< p.length;i++){
(function(index){
setTimeout(function(){
call(index,intercall);
},100);
}(p[i]));
}
}
//获取目录下的所有文件信息
function getDir(dir_path,finalCallback){
var path=node_path.join(__dirname,dir_path);
console.log(path);
var over=[];
var watchProcessDir=[];
watchProcessDir.push(path);
function judgeAllDone(path){
watchProcessDir.splice(watchProcessDir.indexOf(path),1);
//console.log(watchProcessDir.length);
if(watchProcessDir.length==0){
//全部结束了
finalCallback(over);
return true;
}else{
return false;
}
}
function forDir(path){
var fi=fs.readdir(path,function(err,files){
//console.log(files);
if(err){
return false;
}
if(!files||files.length==0){
judgeAllDone(path);
return;
}
myMap(files,function(e,cb){
//console.log('file:'+e);
var paths=node_path.join(path,e);
fs.stat(paths,function(err,file){
if(file.isDirectory()){
//如果是目录那么将paths放入result,等待files遍历完了后,执行[2]
cb(null,paths)
}else{
//如果是文件,设置为空字符串
over.push(paths)
cb(null,'');
//移动到cb上面
//over.push(paths);
}
});
},function(err,results){//[2],进入子目录进行递归
if(results.join('')!=''){
//去掉空字符串
results=results.filter(function(item){
return !!item;
});
watchProcessDir=watchProcessDir.concat(results);
results.forEach(function(e,i){
forDir(e);
});
}
judgeAllDone(path);
})
})
}
forDir(path);
}
getDir('../node_modules',function(over){
console.log('~~~done~~~~file size:%d',over.length);
});
var path = node_path.join(__dirname, dir_path)
var dirs = [];
var over_dir=[];
var over=[];
dirs.push(path)
function forDir(dirs) {
function forFiles(files, file_path) {
var fixdir = [];
files.forEach(function (e, i) {
var e = node_path.join(file_path,e)
fs.stat(e, function (err, stat) {
if (stat.isDirectory()) {
fixdir.push(e)
over_dir.push(e)
}else{
over.push(e)
}
if (i == files.length - 1) {
if(file_path==over_dir[over_dir.length-1]){
console.log(over)
}
if(fixdir.length>0){
forDir(fixdir)
}
}
})
})
}
dirs.forEach(function (e, i) {
fs.readdir(e, function (err, files) {
forFiles(files,e)
})
})
}
forDir(dirs)
代码修改了下
分成2大块
1 多个目录遍历调用
2 处理一个目录下文件类型异步判别的
3 处理指定目录下文件列表异步读取的
1 调用 2 调用 3
3 处理完通知 2 处理完通知1
var path = node_path.join(__dirname, "../");
var dirs = [];
dirs.push(path);
/**
* 处理某个类目下所有文件及目录
* @param files 文件。也可能是目录
* @param file_path 文件或目录的上级目录
* @param callback 一个目录或文件的判断结果的回调
* @param allFilesDoneCallback 所有文件处理完成后的回调函数
*/
function forFiles(files, file_path,callback,allFilesDoneCallback) {
var arrlength=files.length;
if(!files||files.length==0){
allFilesDoneCallback(file_path);
return;
}
files.forEach(function (e, i) {
var fullFilePath = node_path.join(file_path,e);
fs.stat(fullFilePath, function (err, stat) {
var result={
isDir:false,
isFile:true,
file:fullFilePath
};
if (stat.isDirectory()) {
result.isDir=true;
result.isFile=false;
}else{
result.isDir=false;
result.isFile=true;
}
//回调
callback(result);
arrlength--;
//判断是否处理完毕
if(arrlength==0){
//回调所有文件处理完毕
allFilesDoneCallback(file_path);
}
});
});
}
/**
* 处理单个目录
* @param dirPath 目录路径
* @param watchDir 监控的目录列表
* @param callback 当目录处理完毕后的回调函数
*/
function forDir(dirPath,watchDir,callback){
fs.readdir(dirPath, function (err, files) {
var subFiles=[];
forFiles(files,dirPath,function(result){
//如果是目录,继续执行forDir并在之前将目录添加到watchDir
//如果是文件,放入subFiles中
if(result.isDir){
watchDir.push(result.file);
forDir(result.file,watchDir,callback);
}else{
subFiles.push(result.file);
}
},function(processedDirPath){//文件全部处理完毕后,执行回调函数通知指定目录遍历完毕,但不包括子目录
callback(processedDirPath,subFiles);
});
});
}
/**
* 遍历处理多个类目
* @param dirs 多个类目列表
* @param doneCallback 处理完成的回调
*/
function forDirs(dirs,doneCallback) {
var copiedDirs=dirs.slice(0);
var watchDir=[];
var allFiles=[];
copiedDirs.forEach(function(path){
watchDir.push(path);
//回调函数中判断watchDir长度是否为0,如为0,表示所有的目录及其子目录处理完毕了,通知最外层处理完毕
//并将返回的文件信息合并
forDir(path,watchDir,function(processedDirPath,subFiles){
allFiles=allFiles.concat(subFiles);
console.log('%s 处理完成',processedDirPath);
watchDir.splice(watchDir.indexOf(processedDirPath),1);
if(watchDir.length==0){
doneCallback(allFiles);
}
});
})
}
forDirs(dirs,function(fileList){
console.log('所有目录遍历完成,获取到文件个数为:%d',fileList.length);
});