首页 > nodejs异步循环获取目录下所有文件

nodejs异步循环获取目录下所有文件

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);
});
【热门文章】
【热门文章】