Node.JavaScript文件系统中目录的操作

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

[[351532]]

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

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

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

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

中序

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

先序

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

后序 

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

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

深度优先搜索

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

广度优先搜索 

同步创建目录

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

_fs.mkdirSync_是同步创建目录

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

  1. let fs = require("fs"); 
  2. let path = require("path"
  3. function mkdirSync(paths){ 
  4.     let arr = paths.split("/"); 
  5.     for(let i=0;i<arr.length;i++){ 
  6.      let currentPath = arr.slice(0,i+1).join("/"); 
  7.         try{  
  8.          fs.accessSync(currentPath) //如果路径存在  不创建目录 
  9.         }catch(e){ 
  10.            fs.mkdirSync(currentPath) 
  11.         } 
  12.      } 
  13.  } 
  14.  
  15. mkdirSync("a/b/c/d")  //默认创建目录  必须父级存在 才能创建子级 

 异步创建目录

  1. function mkdir(paths,cb){ 
  2.     let arr = paths.split("/"); 
  3.     function next(index){ 
  4.        if(index>=arr.length) return cb(); 
  5.        let currentPath = arr.slice(0,index+1).join("/"); 
  6.        fs.access(currentPath,(err)=>{ 
  7.           if(err){  
  8.               fs.mkdir(currentPath,()=>next(index+1)) 
  9.           }else{   //如果存在则不创建 
  10.               next(index+1) 
  11.           } 
  12.        }) 
  13.     } 
  14.     next(0) 
  15. mkdir("a/b/c/d/e",(err)=>{ 
  16.    console.log("创建完成"); 
  17. }) 

创建目录 

深度删除目录(同步)

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

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

  1. function removeSync(dir){ 
  2.    let statObj = fs.statSync(dir) 
  3.    if(statObj.isDirectory()){ 
  4.       let dirs = fs.readdirSync(dir)   //返回一个数组 
  5.     //   console.log(dirs); 
  6.      for(let i = 0;i<dirs.length;i++){ 
  7.         //把路径进行包装 
  8.          let current =path.join(dir,dirs[i]) 
  9.          removeSync(current) //删除儿子节点 再将自己删除 
  10.      } 
  11.      fs.rmdirSync(dir)  //删除自己 
  12.    }else
  13.        //文件就删除 
  14.        fs.unlinkSync(dir) 
  15.    } 
  16. removeSync("a"

 广度删除目录(同步)

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

  1. while(current = arr[index++]){ 
  2.     let statObj = fs.statSync(current); 
  3.     if(statObj.isDirectory()){ 
  4.         let dirs =fs.readdirSync(current); 
  5.         dirs = dirs.map(d=>path.join(current,d)); //当前儿子的文件夹路径 
  6.         arr = [...arr,...dirs] 
  7.     } 
  8.  } 

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

  1. function wideSync(dir){ 
  2.    let arr = [dir]; 
  3.    let index = 0; 
  4.    let current; //读取的当前项目 
  5.    while(current = arr[index++]){ 
  6.       let statObj = fs.statSync(current); 
  7.       if(statObj.isDirectory()){ 
  8.           let dirs =fs.readdirSync(current); 
  9.           dirs = dirs.map(d=>path.join(current,d)); //当前儿子的文件夹路径 
  10.           arr = [...arr,...dirs] 
  11.       } 
  12.    } 
  13.    //倒叙删除 
  14.    for(let i = arr.length-1;i>=0;i--){ 
  15.        let current = arr[i] 
  16.        let statObj = fs.statSync(current); 
  17.        if(statObj.isDirectory()){ 
  18.            fs.rmdirSync(current
  19.        }else
  20.            fs.unlinkSync(current
  21.        } 
  22.    } 
  23. wideSync("a"

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

  1. function rmdirSeries(dir,callback){ 
  2.     fs.stat(dir,(err,statObj)=>{ 
  3.         if(statObj.isDirectory()){ 
  4.              //读取文件内容 
  5.              fs.readdir(dir,(err,dirs)=>{ 
  6.                  dirs = dirs.map(d=>path.join(dir,d)) 
  7.                  function next(index){ 
  8.                     if(index == dirs.length) return fs.rmdir(dir,callback) 
  9.                     //先取出数组中的第一个  第一个删除后  在删第二个 
  10.                     rmdirSeries(dirs[index],()=>next(index+1)) 
  11.                  } 
  12.                  next(0) 
  13.              }) 
  14.         }else
  15.             fs.unlink(dir,callback) 
  16.         } 
  17.     }) 
  18. rmdirSeries("a",()=>{ 
  19.     console.log("删除成功"); 
  20. }) 

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

  1. function removeDirParalle(dir,callback){ 
  2.     fs.stat(dir,(err,statObj)=>{ 
  3.         if(statObj.isDirectory()){ 
  4.              //读取文件内容 
  5.              fs.readdir(dir,(err,dirs)=>{ 
  6.                  if(dirs.length == 0){ 
  7.                     return fs.rmdir(dir,callback) 
  8.                  } 
  9.                  dirs = dirs.map(d=>{ 
  10.                     let current = path.join(dir,d); 
  11.                     //每个人删除之后就调用done        
  12.                     removeDirParalle(current,done); 
  13.                     return current 
  14.                  }) 
  15.                  //并发删除 
  16.                  let index = 0; 
  17.                  function done(){ 
  18.                      if(++index == dirs.length){ 
  19.                         fs.rmdir(dir,callback) 
  20.                      } 
  21.                  } 
  22.              }) 
  23.         }else
  24.             fs.unlink(dir,callback) 
  25.         } 
  26.     }) 
  27. removeDirParalle("a",()=>{ 
  28.     console.log("删除成功"); 
  29. }) 

 【编辑推荐】

 

责任编辑:姜华 来源: 前端简报
相关推荐

2010-08-04 17:18:09

nfs文件系统

2010-02-25 14:50:59

Linux文件系统

2010-04-15 16:24:10

Unix操作系统

2010-04-08 15:58:24

Unix操作系统

2010-04-22 14:42:34

Aix操作系统

2009-12-22 11:30:38

Linux操作系统

2009-12-10 14:27:07

Linux操作系统

2017-03-30 10:13:11

Linux内核文件系统

2010-01-08 18:01:03

Ubuntu硬盘操作

2010-04-22 14:45:31

Aix操作系统

2022-08-09 15:30:41

Linux

2012-06-08 09:16:16

操作系统

2017-03-30 11:19:33

Linux文件系统目录结构

2020-07-22 14:53:06

Linux系统虚拟文件

2019-05-29 16:33:32

Linux虚拟系统

2019-05-22 09:00:16

Linux虚拟文件系统

2023-08-05 12:58:51

RPC协议服务端

2013-05-27 14:46:06

文件系统分布式文件系统

2012-07-05 09:52:06

EFS文件加密

2023-12-06 09:32:35

Linux系统
点赞
收藏

51CTO技术栈公众号