浅谈Nodejs文件模块中的fs.mkdir和fs.rmdir

本篇文章带大家了解一下Nodejs文件操作fs.mkdir和fs.rmdir。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

【推荐学习:《nodejs 教程》】

fs.mkdir文件目录新增

案例使用

  • 逐级新增目录 会成功打印success
fs.mkdir(a, function (err) {
    // 当a不存在的时候直接创建 a/b会报错
 if (err) {
    console.log(err);
    return;
  }
  console.log(success...);//success
});
  • 跨级在不存在的目录下新增目录 报错啦!!,node本身的内置模块是不支持不存在的目录下新增目录的(这就是我要干的事)

1.gif

fs.mkdir的加强版

递归版本

思路

  • 对要新增的path路径根据/进行切割生成数组缓存

  • index 初始值= 1;对路径对应数组依次进行slice(0, index) 截取后join('/')成path字符串currentPath

  • fs.stat 用于描述文件的状态,如果不存在文件,就发生错误

  • 上一天发生错误调用 fs.mkdir(currentPath, 递归调用自己);

  • 文件存在调用自己

代码实现

function mkdir(pathStr, cb) {
  let pathList = pathStr.split(/);
  // 递归调用fs.mkdir
  let index = 1;
  function make(err) {
    if (err) return cb(err);
    if (index === pathList.length + 1) return cb();
    //每次 调用要将上次的已经生成的文件名做下次的目标文件,
    // 所以 slice(0, index) 第二参数也要 累加
    //slice(0, index) 截取后join('/')  成字符串
    let currentPath = pathList.slice(0, index++).join(/);
    // console.log(pathList.slice(0,index), pathList.slice(0, index));
    fs.stat(currentPath, function (err) {
      if (err) {
        fs.mkdir(currentPath, make);
        console.log({ currentPath });
        // 如果不存在,再创建  fs.mkdir(currentPath, make);
      } else {
        make();
      }
    });
  }
  make();
}

测试:

此时已经不报错了

mkdir(a/b/c/d, function (err) {
  if (err) console.log(err);
   console.log(success...);
});

打印效果

2.gif

3.gif

for循环+await版本

实现思路

  • 以‘/’为基准切割路径为对应数组,对数组进行for循环遍历

  • for循环里existsSync()以同步的方法检测目录是否存在。

  如果目录存在 返回 true ,如果目录不存在 返回false 3. 不存在 fs.mkdir(currentPath)

实现代码

const fs = require(fs).promises; //node11后可以直接.promises
const { existsSync } = require(fs);
async function mkdir(pathStr, cb) {
  let pathList = pathStr.split(/);
  for (let i = 1; i <= pathList.length; i++) {
    let currentPath = pathList.slice(0, i).join(/);
    if (!existsSync(currentPath)) {
      await fs.mkdir(currentPath);
    }
  }
}

调用 将递归调用 平铺称then 链式调用

mkdir(a/b/c/d)
  .then(() => {
    console.log(创建成功);
  })
  .catch((err) => {
    console.log(err);
  });

打印效果

4.gif

5.gif

fs.rmdir文件目录删除

案例使用

对存在子目录的目录直接进行fs.rmdir删除

const fs = require(fs);
const path = require(path);
fs.rmdir(a, function (err) {
  console.log(err);//会报错
});

使用结果(报错)

6.gif

fs.rmdir加强版

串行版本

思路

  • fs.stat 会返回文件的具体信息:文件的状态 文件的信息,修改时间,创建时间,目录状态;fs.stat 的回调里第二参数是获取到文件对象,对象的方法 :isFile,isDirectory

  • isFile 直接 fs.unlink(dir, cb);删除当前文件

  • isDirectory 调用fs.readdir返回子目录组成的数组

  • 对子目录数组进行map遍历&父文件名称+子文件名称拼接path.join(dir, item))

  • 对拼接过的path数组依次进行递归调用自己

  • 子目录全删除后删除本身

代码实现

function rmdir(dir, cb) {
  fs.stat(dir, function (err, statObj) {
    // 1:判断dir的文件信息 statObj 是目录还是 文件
    if (statObj.isDirectory()) {
      // 1.1 读取文件夹fs.readdir 回调函数 里可以拿到文件夹读取结果
      fs.readdir(dir, function (err, dirs) {
        //   遍历 文件夹中文件,path 拼接 父文件名称+ 子文件名称
        dirs = dirs.map((item) => path.join(dir, item));
        // 把目录里面 的拿出来,一个删除后 删除下一个
        let index = 0;
        function step() {
          // 将子文件都删除完后,删除自己
          if (index === dirs.length) return fs.rmdir(dir, cb);
          //删除第一个成功后 继续调用rmdir 删除下一个子文件,直到index===dirs.length 时 删除自己
          rmdir(dirs[index++], step);
        }
        step();
      });
    } else {
      // 1.2 dir是文件 直接删除 用fs.unlink
      fs.unlink(dir, cb);
    }
  });
}

测试

rmdir(a, function () {
  console.log(删除成功);
});

执行结果

7.gif

并行版本

代码实现

const fs = require(fs).promises;
const path = require(path);
async function rmdir(dir) {
  let statObj = await fs.stat(dir);
  if (statObj.isDirectory) {
    let dirs = await fs.readdir(dir);
    await Promise.all(dirs.map((item) => rmdir(path.join(dir, item))));
    await fs.rmdir(dir);
  } else {
    return fs.unlink(dir);
  }
}

调用

rmdir(a).then(() => {
  console.log(并行删除成功);
});

执行结果

8.gif

并行和串行的区别

串行 理解成单线程 要根据上一个执行结束后才能执行下一个 并行 异步执行 彼此之间无依赖关系 那么后者会比前者效率上更高效些些

文件目录的操作本质

  • 文件目录本质:是树形结构数据

  • 文件目录的操作是对树形结构的数据的操作

  • 留个坑位 下次写 树形结构的了解

更多编程相关知识,请访问:编程教学!!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


kindeditor4.x代码高亮功能默认使用的是prettify插件,prettify是Google提供的一款源代码语法高亮着色器,它提供一种简单的形式来着色HTML页面上的程序代码,实现方式如下: 首先在编辑器里面插入javascript代码: 确定后会在编辑器插入这样的代码: <pre
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代码高亮,因为SyntaxHighlighter的应用非常广泛,所以将kindeditor默认的prettify替换为SyntaxHighlighter代码高亮插件 上一篇“让kindeditor显示高亮代码”中已经
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小
JS怎么获取当前时间戳
JS如何判断对象是否为数组
JS怎么获取图片当前宽高
JS对象如何转为json格式字符串
JS怎么获取图片原始宽高
怎么在click事件中调用多个js函数
js如何往数组中添加新元素
js如何拆分字符串
JS怎么对数组内元素进行求和
JS如何判断屏幕大小
js怎么解析json数据
js如何实时获取浏览器窗口大小
原生JS实现别踩白块小游戏(五)
原生JS实现别踩白块小游戏(一)