node文件目錄操作之遍歷刪除目錄

從node目錄刪除學(xué)習(xí)深度優(yōu)先遍歷和廣度優(yōu)先遍歷處理任務(wù)思想浑度。
使用到的模塊:fs path

使用到的方法:(均為同步方法)
let statObj = fs.statSync(path):判斷是文件夾還是文件 statObj.isDirectory() statObj.isFile()

fs.readdirSync(dir):返回值是一個(gè)數(shù)組穆碎,用來(lái)獲取當(dāng)前目錄下的子目錄或者文件企蹭。

fs.rmdirSync(dir):刪除文件夾魂那,注意:只能刪除空文件夾憔杨,不能刪除含有內(nèi)容的文件夾渐北,因此刪除文件夾采用先刪除子文件及子目錄再刪除父級(jí)文件目錄。

fs.unlinkSync(dir):刪除文件
path.join(path1,path2):將所有path片段拼接在一起多律,生成規(guī)范目錄鲜结。

深度優(yōu)先刪除目錄

思路:如下圖所示結(jié)構(gòu)雳灾,深度優(yōu)先遍歷思路就是從根節(jié)點(diǎn)A觸發(fā)钦睡,找到B之后拯钻,繼續(xù)沿著B往下找钧嘶,找到E繼續(xù)沿著E往下找棠众,發(fā)現(xiàn)E沒(méi)有子節(jié)點(diǎn),那么就將E刪除有决,接著刪除F闸拿,再刪除B,再去找C及其子節(jié)點(diǎn)书幕,然后是D及其子節(jié)點(diǎn)新荤。


深度優(yōu)先遍歷
function rmDirDeepSync(dir) {
    let statObj = fs.statSync(dir);
    if (statObj.isDirectory()) {
        let dirs = fs.readdirSync(dir);
        for(let i = 0; i < dirs.length; i++ ) {
            rmDirDeepSync(path.join(dir, dirs[i]))
        }
        fs.rmdirSync(dir);
    } else {    
        fs.unlinkSync(dir);
    }
}

rmDirDeepSync('A');

廣度優(yōu)先刪除目錄

思路:如下圖所示結(jié)構(gòu),廣度優(yōu)先遍歷的思路是使用一個(gè)數(shù)組按照順序存儲(chǔ)所有的節(jié)點(diǎn)台汇,然后使用一個(gè)指針苛骨,依次向后挪動(dòng)篱瞎,指針?biāo)赶虻氖悄夸浀脑挘俅伪闅v出子節(jié)點(diǎn)智袭,并拼接至數(shù)組奔缠。然后從后到前依次刪除。
比如下圖在數(shù)組中最終是這個(gè)樣子的[ 'A', 'A/B', 'A/C', 'A/D', 'A/B/E', 'A/B/F' ]吼野。

廣度優(yōu)先遍歷
function rmDirWideSync(dir){
    let arr = [dir]; // 存儲(chǔ)數(shù)組
    let index = 0; // 指針
    let current; // 當(dāng)前指針指向的元素
    while(current = arr[index]) {
        let statObj = fs.statSync(current);
        if(statObj.isDirectory()){
            let dirArr = fs.readdirSync(current).map(d => path.join(current, d));
            arr = [...arr, ...dirArr];
        }
        index++;
    }
    for (let i = arr.length - 1; i >=0; i--) { // 倒序刪除校哎,先刪除子級(jí),再刪除父級(jí)
        let statObj = fs.statSync(arr[i]);
        if(statObj.isDirectory()) {
            fs.rmdirSync(arr[i]);
        } else {
            fs.unlinkSync(arr[i]);
        }
    }
}
rmDirWideSync('A');

總結(jié):同步刪除有廣度優(yōu)先和深度優(yōu)先兩種方案瞳步,異步刪除也有兩種方案闷哆,異步串行刪除,和異步并行刪除单起。

異步串行:(采用深度遞歸抱怔,深度優(yōu)先方案)

function rmDirAsyncSerie(dir,cb) {
    fs.stat(dir, (err, stats) => { 
        if(stats.isDirectory()) {
            fs.readdir(dir, (err, dirs) => {
                dirs = dirs.map((item) => {
                    return path.resolve(dir, item);
                })
                function next(index) {
                    if(index === dirs.length) {
                        fs.rmdir(dir, cb);
                        return;
                    }
                    rmDirAsyncSerie(dirs[index], () => {
                        next(++index);
                    });
                }
                next(0);
            })
        } else {
            fs.unlink(dir, cb);
        }
    });
}
rmDirAsyncSerie('a', () => {
  console.log('刪除完成');
});

異步并行:異步的好處就是任務(wù)可以并行執(zhí)行。

function rmDirAsyncParalle(dir, cb) {
    fs.stat(dir, (err, stats) => {
        if(stats.isDirectory()) {
            fs.readdir(dir, (err, dirs) => {
                if (dirs.length === 0) {
                    fs.rmdir(dir, cb);
                    return;
                }
                dirs.map((d) =>{
                    let current = path.join(dir, d);
                    rmDirAsyncParalle(current, done);
                })
                let index = 0;
                function done() {
                    index++;
                    if(index === dirs.length) {
                        fs.rmdir(dir, cb);
                    }
                }
            })
        }else{
            fs.unlink(dir, cb);
        }
    })
}

rmDirAsyncParalle('a', () => {
    console.log('刪除成功');
})

并行刪除效率會(huì)更高嘀倒,并行和串行的區(qū)別就在于屈留,并行是在循環(huán)中執(zhí)行刪除方法的,串行是執(zhí)行完本次刪除任務(wù)后测蘑,再去調(diào)用下一個(gè)刪除方法的灌危。

注意觀察串行刪除的next方法和并行刪除的done方法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末碳胳,一起剝皮案震驚了整個(gè)濱河市勇蝙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌挨约,老刑警劉巖味混,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異诫惭,居然都是意外死亡翁锡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門夕土,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)馆衔,“玉大人,你說(shuō)我怎么就攤上這事隘弊」猓” “怎么了荒适?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵梨熙,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我刀诬,道長(zhǎng)咽扇,這世上最難降的妖魔是什么邪财? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮质欲,結(jié)果婚禮上树埠,老公的妹妹穿的比我還像新娘。我一直安慰自己嘶伟,他們只是感情好怎憋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著九昧,像睡著了一般绊袋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上铸鹰,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天癌别,我揣著相機(jī)與錄音,去河邊找鬼蹋笼。 笑死展姐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的剖毯。 我是一名探鬼主播圾笨,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼速兔!你這毒婦竟也來(lái)了墅拭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤涣狗,失蹤者是張志新(化名)和其女友劉穎谍婉,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體镀钓,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡穗熬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丁溅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唤蔗。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖窟赏,靈堂內(nèi)的尸體忽然破棺而出妓柜,到底是詐尸還是另有隱情,我是刑警寧澤涯穷,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布棍掐,位于F島的核電站,受9級(jí)特大地震影響拷况,放射性物質(zhì)發(fā)生泄漏作煌。R本人自食惡果不足惜掘殴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望粟誓。 院中可真熱鬧奏寨,春花似錦、人聲如沸鹰服。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)悲酷。三九已至仍源,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間舔涎,已是汗流浹背笼踩。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留亡嫌,地道東北人嚎于。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像挟冠,于是被迫代替她去往敵國(guó)和親于购。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355