溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

node中實(shí)現(xiàn)刪除目錄的幾種方法

發(fā)布時(shí)間:2020-09-04 17:08:40 來(lái)源:腳本之家 閱讀:164 作者:UlaHalal 欄目:web開(kāi)發(fā)

由于刪除目錄只能刪除空目錄(如果有子文件或文件夾要先刪除)

目錄結(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的類(lèi)型(文件還是文件夾,如果是文件直接刪除, 如果是文件夾, 去取當(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í)有所幫助,也希望大家多多支持億速云。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI