文件夹相关操作

245 阅读2分钟

文件夹操作依赖的也是 fs 模块。

几个本文要用到的相关模块

fs.exists(被弃用了)

判断是否存在,因为该方法的回调函数第一个值不是 err 对象,不符合 node 回调函数的相关规范,已经被弃用了。

fs.exists('a/b', function(exists) {
  console.log(exists); // false
});

fs.stat 或 fs.lstat

查看文件状态,配合 fs.isDirectory 可以判断是否是文件夹

// 文件不存在则报错
fs.stat('a/b', function(err, stat) {
  console.log(err); // no such file or directory, stat 'a/b'
  console.log(stat);
});

// 文件存在返回文件信息
fs.stat(path.resolve(__dirname, 'fs.js'), function(err, stat) {
  console.log(stat); // stats { ... } 
});

// 判断文件夹是否存在
fs.stat(path.resolve(__dirname, 'fs.js'), function(err, stat) {
  console.log(stat.isDirectory()); // false 不是文件夹
});

fs.readdir 读取子目录

它只能读取一层目录,返回子目录和文件组成的数组,如果没有子文件/文件夹,返回空数组

// 加入当前目录下有 a/b/c/d 和 fs.js
fs.readdir(path.resolve(__dirname), function(err, dirs) {
  console.log(dirs); // [ 'a', 'fs.js' ]
});

// 目标文件不是个文件夹,报错
fs.readdir(path.resolve(__dirname, 'fs.js'), function(err, dirs) {
  console.log(err); //  not a directory
});

fs.mkdir 创建文件夹

const fs = require('fs');
const path = require('path');

// 创建 a 文件夹
fs.mkdir(path.resolve(__dirname, 'a'), function(err) {
  console.log(err); // null
});

// 不存在的父级目录则报错
fs.mkdir(path.resolve(__dirname, 'a/b/c/d'), function(err) {
  console.log(err); // no such file or directory
});

// 创建文件夹,包括不存在的父级文件夹
fs.mkdir(path.resolve(__dirname, 'a/b/c/d'), { recursive: true },function(err) {
  console.log(err); // null
});

手写实现完备的 mkdir(不存在则创建)

function mkdir(dirpath, cb) {
    let dirs = dirpath.split('/'); // a   a/b  a/b/c/   a/b/c/d
    let index = 0;

    function next() {
        if (index == dirs.length - 1) return cb(null);
        let p = dirs.slice(0, ++index).join('/');
        fs.stat(p, function(err) {
            if (err) {
                fs.mkdir(p, next); // 异步创建
            } else {
                next();
            }
        })
    }
    next()
}

mkdir('a/b/c/d/e', function() {
    console.log('创建成功')
});

fs.rmdir 删除文件夹

// 目录不存在 报错
fs.rmdir(path.resolve(__dirname, 'bbb'), function(err) {
  console.log(err); // no such file or directory
});

// 非空文件夹不能删除
fs.rmdir(path.resolve(__dirname, 'a'), function(err) {
  console.log(err); // directory not empty
});

// 递归删除文件夹
fs.rmdir(path.resolve(__dirname, 'a'), { recursive: true }, function(err) {
  console.log(err); // directory not empty
});

手写实现完备的 rmdir(非空则递归删除)

// a/b/c
function rmdir(p) {
  let arr = fs.readdirSync(p);


  for (var i in arr) {
    let curPath = path.join(p, '/', arr[i]);
    let stats = fs.statSync(curPath);
    
    stats.isFile() ? fs.unlinkSync(curPath) : rmdir(curPath);
  }

  fs.rmdirSync(p);
}

rmdir(path.resolve(__dirname, 'a'));