node中實(shí)現(xiàn)刪除目錄的幾種方法
由于刪除目錄只能刪除空目錄(如果有子文件或文件夾要先刪除)
目錄結(jié)構(gòu)算是典型的二叉樹(shù)模型,所以涉及到遍歷樹(shù)結(jié)構(gòu)
二叉樹(shù)遍歷(分為深度和廣度,以及先序,中序,后序之分)
以下以深度先序解決目錄刪除
在node中由于主線程為單線程, 可以采取串行方式和并行方式
無(wú)論用什么方法刪除,就一點(diǎn)核心: 如果是文件直接刪除, 如果不是就刪除所有子文件或子目錄, 然后記得(一定記得刪除自己)
深度先序(串行)
深度先序(串行 回調(diào)方式)
const fs = require('fs')
const path = require('path')
function rmdir(filePath, callback) {
// 先判斷當(dāng)前filePath的類型(文件還是文件夾,如果是文件直接刪除, 如果是文件夾, 去取當(dāng)前文件夾下的內(nèi)容, 拿到每一個(gè)遞歸)
fs.stat(filePath, function(err, stat) {
if(err) return console.log(err)
if(stat.isFile()) {
fs.unlink(filePath, callback)
}else {
fs.readdir(filePath, function(err, data) {
if(err) return console.log(err)
let dirs = data.map(dir => path.join(filePath, dir))
let index = 0
!(function next() {
// 此處遞歸刪除掉所有子文件 后刪除當(dāng)前 文件夾
if(index === dirs.length) {
fs.rmdir(filePath, callback)
}else {
rmdir(dirs[index++],next)
}
})()
})
}
})
}
rmdir('a', function() {
console.log('刪除成功')
})
深度先序 (串行 promise寫(xiě)法)
const fs = require('fs')
const path = require('path')
function rmdirPromise(filePath) {
return new Promise((resolve, reject) => {
fs.stat(filePath, function(err, stat) {
if(err) reject(err)
if(stat.isFile()) {
fs.unlink(filePath, function(err) {
if(err) reject(err)
resolve()
})
}else {
fs.readdir(filePath, function(err, dirs) {
if(err) reject(err)
dirs = dirs.map(dir => path.join(filePath, dir)) // a/b a/c
let index = 0;
(function next() {
if(index === dirs.length) {
fs.rmdir(filePath, function(err) {
if(err) reject(err)
resolve()
})
}else {
rmdirPromise(dirs[index++]).then(() => {
next()
}, err => {
reject(err)
})
}
})()
})
}
})
})
}
rmdirPromise('a').then(() => {
console.log('刪除成功')
})
深度先序 (串行 async await寫(xiě)法)
// 在node v10.0.0+版本中fs模塊提供 promise 寫(xiě)法 const fs = require('fs').promises
// 如果在node 10之前的版本中可以引入第三方模塊 mz const fs = require('mz/fs') 用法一致 https://www.npmjs.com/package/mz
const fs = require('fs').promises
const path = require('path')
async function rmdirAsync(filePath) {
let stat = await fs.stat(filePath)
if (stat.isFile()) {
await fs.unlink(filePath)
} else {
let dirs = await fs.readdir(filePath)
dirs = dirs.map(dir => path.join(filePath, dir))
let index = 0;
(async function next() {
if (index === dirs.length) {
await fs.rmdir(filePath)
} else {
await rmdirAsync(dirs[index++])
await next()
}
})()
}
}
rmdirAsync('a').then(() => {
console.log('刪除成功')
}, (err) => {
console.log('err', err)
})
深度先序 (并行)
深度先序 (并行 回調(diào)寫(xiě)法)
const fs = require('fs').promises
const path = require('path')
function rmdir(filePath, callback) {
fs.stat(filePath, function(err,stat) {
if(err) return console.log(err)
if(stat.isFile()) {
fs.unlink(filePath, callback)
}else {
fs.readdir(filePath, function(err, dirs) {
if(err) return console.log(err)
// 此處要添加dirs.length的驗(yàn)證,不然如果length為0 后面的forEach不執(zhí)行, 就刪不掉當(dāng)前目錄了, 也執(zhí)行不了callback
if(dirs.length === 0) {
fs.rmdir(filePath, callback)
}
dirs = dirs.map(dir => path.join(filePath, dir))
// 通過(guò)計(jì)數(shù)的方式來(lái)判斷是否子目錄都刪除了
let index = 0
function done() {
if(++index === dirs.length) {
fs.rmdir(filePath, callback)
}
}
// 何為并行? a下有兩個(gè)目錄b, c,那么同時(shí)將b, c的刪除都推到event Loop中,用for循環(huán)實(shí)現(xiàn)
dirs.forEach(dir => {
// 通過(guò)done回調(diào)的方式來(lái)控制js執(zhí)行流程(LazyMan問(wèn)題也是這么解決的)
rmdir(dir, done)
});
})
}
})
}
rmdir('a', function() {
console.log('刪除成功')
})
深度先行 (并行promise寫(xiě)法)
const fs = reqire('fs')
const path = require('path')
function rmdirPromise(filePath) {
return new Promise((resolve, reject) => {
fs.stat(filePath, function (err, stat) {
if (err) reject(err)
if (stat.isFile()) {
fs.unlink(filePath, function (err) {
if (err) reject(err)
resolve()
})
} else {
fs.readdir(filePath, function (err, dirs) {
if (err) reject(err)
dirs = dirs.map(dir => path.join(filePath, dir))
dirs = dirs.map(dir => rmdirPromise(dir))
Promise.all(dirs).then(() => {
fs.rmdir(filePath, resolve)
})
})
}
})
})
}
rmdirPromise('a').then(() => {
console.log('刪除成功')
})
深度先序 (并行 async + await寫(xiě)法)
const fs = require('fs').promises
const path = require('path')
async function rmdirAsync(filePath) {
let stat = await fs.stat(filePath)
if(stat.isFile()) {
await fs.unlink(filePath)
}else {
let dirs = await fs.readdir(filePath)
dirs = dirs.map(dir => rmdirAsync(path.join(filePath, dir)))
await Promise.all(dirs)
await fs.rmdir(filePath)
}
}
rmdirAsync('a').then(() => {
console.log('刪除成功')
})
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Node.js進(jìn)行文件讀取與復(fù)制的系統(tǒng)總結(jié)
這篇文章主要為大家詳細(xì)介紹了Node.js中文件讀取與復(fù)制相關(guān)內(nèi)容的系統(tǒng)總結(jié),包括 同步讀取,異步讀取,復(fù)制操作等,有需要的小伙伴可以跟隨小編一起了解下2025-04-04
Nodejs把接收?qǐng)D片base64格式保存為文件存儲(chǔ)到服務(wù)器上
這篇文章主要介紹了Nodejs把接收?qǐng)D片base64格式保存為文件存儲(chǔ)到服務(wù)器上,文中代碼較簡(jiǎn)短,需要的朋友可以參考下2018-09-09
Vue+Node實(shí)現(xiàn)的商城用戶管理功能示例
這篇文章主要介紹了Vue+Node實(shí)現(xiàn)的商城用戶管理功能,結(jié)合實(shí)例形式詳細(xì)分析了商城用戶管理的前臺(tái)登錄、校驗(yàn)、跳轉(zhuǎn)、退出等相關(guān)操作技巧,需要的朋友可以參考下2019-12-12
node.js部署之啟動(dòng)后臺(tái)運(yùn)行forever的方法
今天小編就為大家分享一篇node.js部署之啟動(dòng)后臺(tái)運(yùn)行forever的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
node.js中的fs.symlink方法使用說(shuō)明
這篇文章主要介紹了node.js中的fs.symlink方法使用說(shuō)明,本文介紹了fs.symlink的方法說(shuō)明、語(yǔ)法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下2014-12-12
Node.js+ES6+dropload.js實(shí)現(xiàn)移動(dòng)端下拉加載實(shí)例
這個(gè)demo服務(wù)由Node搭建服務(wù)、下拉加載使用插件dropload,數(shù)據(jù)渲染應(yīng)用了ES6中的模板字符串。有興趣的小伙伴可以自己嘗試下2017-06-06
Node koa服務(wù)器實(shí)現(xiàn)獲取客戶端ip
這篇文章主要為大家詳細(xì)介紹了Node koa服務(wù)器實(shí)現(xiàn)獲取客戶端ip的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解下2025-02-02
npm?install?-g?@vue/cli常見(jiàn)問(wèn)題解決匯總
這篇文章主要給大家介紹了關(guān)于npm?install?-g?@vue/cli常見(jiàn)問(wèn)題解決的相關(guān)資料,文中通過(guò)實(shí)例代碼將解決的方式介紹的非常詳細(xì),對(duì)遇到這個(gè)問(wèn)題的朋友具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-08-08

