首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >node.js文件系统中目录的操作

node.js文件系统中目录的操作

作者头像
小丑同学
发布于 2020-11-17 11:06:46
发布于 2020-11-17 11:06:46
2.2K0
举报
文章被收录于专栏:小丑的小屋小丑的小屋

谈到对目录的操作,需要涉及到对目录遍历,其实目录也是我们可以把它看成一颗树。树是一种非线性的数据结构,被用来存储具有层级关系的数据,还被用来存储有序列表,其中有一种特殊的树:二叉树。

有一种特殊的二叉树叫二叉查找树(BST),其他的特点是:相对较小的值保存在左节点中,较大的值保存在右节点中,因为这个特点使查找的效率特别高。

遍历二叉查找树有三种方式:中序,先序和后序

  • 中序:按照节点上的键值,已升序访问树中所有节点,先访问左子树,在访问根节点,最后访问右子树。

中序

  • 先序:先访问根节点,然后以同样方式访问左子树和右子树

先序

  • 后序:先访问叶子节点,从左子树到右子树,再到根节点

后序

还有两种搜索方法:深度优先搜索和广度优先搜索

  • 深度优先搜索时从一条路径的起始顶点开始一直到最后一个顶点,然后回溯,继续追溯下一条路径,直到到达最后的顶点,如此往复,知道没有路径为止。

深度优先搜索

  • 广度优先搜索是从第一个顶点开始,首先检查最靠近第一个顶点的一层,再逐渐向下移动到离起始顶点最远的一层。

广度优先搜索

同步创建目录

_fs.accessSync_是fs.access的同步方法用于检查文件是否存在,检查是否对文件是否有读写权限,当操作成功时返回值和异步方法执行成功相同,但操作失败时会抛出异常。

_fs.mkdirSync_是同步创建目录

话不多说,我们直接上代码

代码语言:javascript
复制
let fs = require("fs");
let path = require("path")
function mkdirSync(paths){
    let arr = paths.split("/");
    for(let i=0;i<arr.length;i++){
     let currentPath = arr.slice(0,i+1).join("/");
        try{ 
         fs.accessSync(currentPath) //如果路径存在  不创建目录
        }catch(e){
           fs.mkdirSync(currentPath)
        }
     }
 }

mkdirSync("a/b/c/d")  //默认创建目录  必须父级存在 才能创建子级

异步创建目录

代码语言:javascript
复制
function mkdir(paths,cb){
    let arr = paths.split("/");
    function next(index){
       if(index>=arr.length) return cb();
       let currentPath = arr.slice(0,index+1).join("/");
       fs.access(currentPath,(err)=>{
          if(err){ 
              fs.mkdir(currentPath,()=>next(index+1))
          }else{   //如果存在则不创建
              next(index+1)
          }
       })
    }
    next(0)
}
mkdir("a/b/c/d/e",(err)=>{
   console.log("创建完成");
})

创建目录

深度删除目录(同步)

fs.stat() 方法用于查询文件信息,可以用于查询文件的大小、创建时间、权限等相关信息。fs.stat() 是异步方法,还有一个同步方法 fs.statSync(path)返回一个对象

思路是:一个分支上先删除儿子再删除自己,然后到另一个分支上删除儿子再删除自己。

代码语言:javascript
复制
function removeSync(dir){
   let statObj = fs.statSync(dir)
   if(statObj.isDirectory()){
      let dirs = fs.readdirSync(dir)   //返回一个数组
    //   console.log(dirs);
     for(let i = 0;i<dirs.length;i++){
        //把路径进行包装
         let current =path.join(dir,dirs[i])
         removeSync(current) //删除儿子节点 再将自己删除
     }
     fs.rmdirSync(dir)  //删除自己
   }else{
       //文件就删除
       fs.unlinkSync(dir)
   }
}
removeSync("a")

广度删除目录(同步)

思路:通过while循环横向列出所有文件的路径,然后通过倒叙删除。

代码语言:javascript
复制
   while(current = arr[index++]){
      let statObj = fs.statSync(current);
      if(statObj.isDirectory()){
          let dirs =fs.readdirSync(current);
          dirs = dirs.map(d=>path.join(current,d)); //当前儿子的文件夹路径
          arr = [...arr,...dirs]
      }
   }

结果:[ 'a', 'a\b', 'a\b\c', 'a\b\c\d' ]

代码语言:javascript
复制
function wideSync(dir){
   let arr = [dir];
   let index = 0;
   let current; //读取的当前项目
   while(current = arr[index++]){
      let statObj = fs.statSync(current);
      if(statObj.isDirectory()){
          let dirs =fs.readdirSync(current);
          dirs = dirs.map(d=>path.join(current,d)); //当前儿子的文件夹路径
          arr = [...arr,...dirs]
      }
   }
   //倒叙删除
   for(let i = arr.length-1;i>=0;i--){
       let current = arr[i]
       let statObj = fs.statSync(current);
       if(statObj.isDirectory()){
           fs.rmdirSync(current)
       }else{
           fs.unlinkSync(current)
       }
   }
}
wideSync("a")

深度删除目录(串行异步)

代码语言:javascript
复制
function rmdirSeries(dir,callback){
    fs.stat(dir,(err,statObj)=>{
        if(statObj.isDirectory()){
             //读取文件内容
             fs.readdir(dir,(err,dirs)=>{
                 dirs = dirs.map(d=>path.join(dir,d))
                 function next(index){
                    if(index == dirs.length) return fs.rmdir(dir,callback)
                    //先取出数组中的第一个  第一个删除后  在删第二个
                    rmdirSeries(dirs[index],()=>next(index+1))
                 }
                 next(0)
             })
        }else{
            fs.unlink(dir,callback)
        }
    })
}
rmdirSeries("a",()=>{
    console.log("删除成功");
})

深度删除目录(并行异步)

代码语言:javascript
复制
function removeDirParalle(dir,callback){
    fs.stat(dir,(err,statObj)=>{
        if(statObj.isDirectory()){
             //读取文件内容
             fs.readdir(dir,(err,dirs)=>{
                 if(dirs.length == 0){
                    return fs.rmdir(dir,callback)
                 }
                 dirs = dirs.map(d=>{
                    let current = path.join(dir,d);
                    //每个人删除之后就调用done       
                    removeDirParalle(current,done);
                    return current
                 })
                 //并发删除
                 let index = 0;
                 function done(){
                     if(++index == dirs.length){
                        fs.rmdir(dir,callback)
                     }
                 }
             })
        }else{
            fs.unlink(dir,callback)
        }
    })
}
removeDirParalle("a",()=>{
    console.log("删除成功");
})

最后

切身体会,为什么程序员总是带着耳机?

吐槽一下,有一个安静的工作环境是多么的重要,一早晨被杂音笼罩真的是烦呀,神烦的,感觉都快要爆炸了。可爱的程序员们真的是不容易。for%……¥&*……#%@%脑细胞都死完了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-10,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 同步创建目录
  • 异步创建目录
  • 深度删除目录(同步)
  • 广度删除目录(同步)
  • 深度删除目录(串行异步)
  • 深度删除目录(并行异步)
  • 最后
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档