Structure-study-Node(fs遍历)

293 阅读1分钟

fs对文件夹的操作

1、创建目录

  • mkdir
  • rmdir
  • readdir
    function mkdir(paths,callback){
        paths = paths.split('/');
        let index = 1;
        function next(){
            let dirPath = paths.slice(0,index++).join('/');
            fs.access(dirPath,function(err){
                if(err){ // 不存在 创建目录
                    fs.mkdir(dirPath,next)
                }else{
                    next() // 存在 创建下一层
                }
            })
        }
        next()
    }

2、删除目录

注意先删除儿子 在删除父亲

简单删除

只有一级

   fs.readdir('a',function(err,dirs){
       // 拼接路径
       dirs = dirs.map(dir=>path.join('a',dir))
       dirs.forEach(dir=>{
           // 判断当前路径状态
           fs.stat(dir,function(err,statObj){
               if(statObj.isFile()){
                   // 删除文件
                   fs.unlink(dir,function(){})
               }else{
                   // 删除文件夹
                   fs.rmdir(dir,()=>)
               }
           })
       })
   }) 

递归删除目录

  • 先序深度串联

next 函数 递归

    function preSeriesDeep(dir,callback){
        // 先删除子节点 在删除父节点
        fs.stat(dir,function(err,statObj){
            if(statObj.isFile()){
                // 文件直接删除
                fs.unlink(dir,callback)
            }else{
                fs.readdir(dir,function(err,dirs){
                    dirs = dirs.map(item=>path.join(dir,item))
                    let index = 0;
                    function next(){
                        // 取出第一个删除掉
                        if(index == dirs.length) return fs.rmdir(dir,callback)
                        let currentPath = dirs[index++]
                        // 删除当前第一个儿子 成功后删除第二个儿子
                        preSeriesDeep(currentPath,next)
                    }
                    next()
                })
            }
        })
    }
  • 先序深度并行
   function preParallelDeep(dir,callback){
       fs.stat(dir,function(err,stat){
           if(stat.isFile){
               fs.unlink(dir,callback)
           }else{
               fs.readdir(dir,function(err,dirs){
                   dirs = dirs.map(item=>path.join(dir,item))
                   
                   if(dirs.length === 0){
                       return fs.rmdir(dir,callback)
                   }
                   let index = 0;
                   function done() {
                       if(++index === dirs.length) return fs.rmdir(dir,callback)
                   }
                   dirs.forEach(dir=>{
                      preParallelDeep(dir,done) 
                   })
               })
           }
       })
   }
  • 先序深度并行 (promise)
    function preParallDeep(dir){
        return new Promise((resolve,reject)=>{
            fs.stat(dir,function(err,statObj){
                if(statObj.isFile()){
                    fs.unlink(dir,resolve)
                }else{
                    fs.readdir(dir,function(err,dirs){
                        dirs = dirs.map(item=>preParallDeep(path.join(dir,item)))
                        Promise.all(dirs).then(()=>{
                           fs.rmdir(dir,resolve) 
                        })
                    })
                }
            })
        })
    }
  • 先序深度并行 (async + await)
    let {unlink,readdir,stat,rmdir} = require('fs').promises
    async function preParallDeep(dir){
        let statObj = await stat(dir)
        if(statObj.isFile()){
            await unlink(dir)
        }else{
           let dirs = await readdir(dir)
           dirs = dirs.map(item=>preParallDeep(path.join(dir,item))) 
           await Promise.all(dirs)
           await rmdir(dir)
        }
    }
  • 广度
    function wide(dir){
        let arr = [dir];
        let index = 0;
        let current;
        // 队列思想
        while(current = arr[index++]){
           let dirs = fs.readdirSync(current)
           dirs = dirs.map(item=>path.join(current,item)) 
           arr = [...arr,...dirs];
        }
        // 循环arr 逆序删除
    }