fs模組之刪除目錄

More發表於2018-07-03

刪除目錄的步驟

  1. 要刪除目錄 需要先把這個目錄中的內容先讀出來
  2. 判斷當前目錄下 是檔案還是資料夾
  3. 刪除目錄 fs.rmdirSync 刪除檔案就用fs.unlinkSync

(1)先序深度優先

同步版本

let fs= require('fs')  //使用fs模組來實現所有有關檔案及目錄的建立、寫入及刪除操作。
let path = require('path'); //用於處理檔案與目錄的路徑。path.resolve() path.join()常用
function removeDir(){
    let statObj = fs.statSync(p); // fs.statSync同步讀取檔案狀態,判斷是檔案目錄還是檔案。
    if(statObj.isDirectory()){ //如果是目錄
        let dirs = fs.readdirSync(p) //fs.readdirSync()同步的讀取目標下的檔案 返回一個不包括 '.''..' 的檔名的陣列['b','a']
        dirs = dirs.map(dir => path.join(p, dir))  //拼上完整的路徑
        for (let i = 0; i < dirs.length; i++) {
            // 深度 先將兒子移除掉 再刪除掉自己
            removeDir(dirs[i]);
        }
        fs.rmdirSync(p); //刪除目錄
    }else{
        fs.unlinkSync(p); //刪除檔案
    }
}
removeDir('a');
複製程式碼

非同步版本

let fs = require('fs');
let path = require('path');
function removeDir(p, callback) {
    fs.stat(p, (err, statObj) => {
        if (statObj.isDirectory()) {
            fs.readdir(p, function(err, dirs) {//讀取p下面的檔案
                // 非同步怎麼遞迴?
                // next函式用來遞迴的
                dirs = dirs.map(dir => path.join(p, dir));
                function next(index){
                    if index=== dirs.length return fs.rmdir(p, callback)
                    let files = dirs[index];
                    removeDir(files,()=>{
                        next(index + 1)
                    })
                }
                next(0)
            })
        } else { // 檔案刪除執行callback即可
            fs.unlink(p, callback);
        }
    });
}
removeDir('a', function() {
    console.log('刪除成功了')
});
複製程式碼

promise 先序深度優先

let fs = require('fs');
let path = require('path');
function removeDir(p) {
    return new Promise((resolve,reject)=>{  //返回一個promise物件   
        fs.stat(p,(err,statObj)=>{ // 非同步讀取檔案判斷檔案型別 是目錄 遞迴 否則就刪除即可
             if(statObj.isDirectory()){
                fs.readdir(p, function(err, dirs) { //讀取p下面的檔案
                    // 對映路徑
                    dirs = dirs.map(dir => path.join(p, dir));
                    // 對映promise
                    dirs = dirs.map(dir => removeDir(dir));// 遞迴呼叫,p下面的檔案再次呼叫判斷刪除方法
                    // 刪除完兒子後 刪除自己
                    Promise.all(dirs).then(() => {
                        fs.rmdir(p, resolve);
                    });
                });
             }else{
                 fs.unlink(p, resolve);
             }
            
        }
    }
    
}
removeDir('a');
複製程式碼

async + await 先序深度優先

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

let util = require('util');
     //util 是一個 Node.js 核心模組,提供了一些常用函式,用於彌補核心 JavaScript 的功能過於精簡的不足。這些函式都包含在 util 模組中,可以通過引用模組來使用它們。
let stat = util.promisify(fs.stat);//判斷檔案型別
    //util.promisify將一個接收回撥函式引數的函式轉換成一個返回Promise的函式。
let readdir = util.promisify(fs.readdir);//判斷檔案型別下面的檔案
let rmdir = util.promisify(fs.rmdir);//刪除目錄
let unlink = util.promisify(fs.unlink);//刪除檔案
async function removeDir(p){
     let statObj = await stat(p);
     if(statObj.isDirectory()){
        let dirs = await readdir(p);
        dirs = dirs.map(dir => path.join(p, dir)); 
        dirs = dirs.map(dir => removeDir(dir));
        await Promise.all(dirs);
        await rmdir(p)
     }else{
        // 要等待檔案刪除後 才讓promise執行完 所以需要await
        await unlink(p);
     }
}
removeDir('a').then(()=>{
    console.log('刪除成功')
})
複製程式碼

(2)先序廣度優先

// 講a,a/b,a/c.js,a/b/d,a/b/d/f 放到一個陣列中。

let fs = require('fs');
let path = require('path');
function removeDir(p){
  let arr=[p];
  let index=0;

  while(current = arr[index++]){
       let statObj = fs.statSync(current);
       if (statObj.isDirectory()) {
          let dirs = fs.readdirSync(current);
          arr = [...arr, ...dirs.map(d => path.join(current, d))];
          //[ 'a', 'a/a.js', 'a/b' ]
          //[ 'a', 'a/a.js', 'a/b', 'a/b/c' ]
          //[ 'a', 'a/a.js', 'a/b', 'a/b/c' ]

        }
    }
    for (let i = arr.length - 1; i >= 0; i--) {
        let statObj = fs.statSync(arr[i]);
        if (statObj.isDirectory()) {
            fs.rmdirSync(arr[i])
        } else {
            fs.unlinkSync(arr[i])
        }
    }
   
  
}
removeDir('a')
複製程式碼

相關文章