当前位置: 首页 > 后端技术 > Node.js

删除节点中的目录

时间:2023-04-04 01:35:05 Node.js

由于删除目录只能删除空目录(如果有子文件或文件夹,则先删除),目录结构是典型的二叉树模型,所以涉及遍历树结构。二叉树遍历(分为深度和广度,以及前序、中序、后序)下面是按深度顺序解决目录删除。由于node中的主线程是单线程的,可以采用串行和并行的方式。不管用什么方法删除,只是一个小核心:如果是文件,直接删除,如果不是,直接删除删除所有子文件或子目录,然后记住(一定要记得自己删除)depthfirstorder(serial)depthfirstorder(serial回调方式)constfs=require('fs')constpath=require('path')functionrmdir(filePath,callback){//首先判断当前filePath的类型(文件或文件夹,如果是文件,直接删除,如果是文件夹,获取当前文件夹的内容,每次递归获取)fs.stat(filePath,function(err,stat){if(err)returnconsole.log(err)if(stat.isFile()){fs.unlink(filePath,callback)}else{fs.readdir(filePath,function(err,data){if(err)returnconsole.log(err)letdirs=data.map(dir=>path.join(filePath,dir))letindex=0!(functionnext(){//这里删除递归删除所有子文件后的当前文件夹if(index===dirs.length){fs.rmdir(filePath,callback)}else{rmdir(dirs[index++],next)}})()})}})}rmdir('a',function(){console.log('删除成功')})深度顺序(串行promise写法)constfs=require('fs')constpath=require('path')functionrmdirPromise(filePath){returnnewPromise((resolve,reject)=>{fs.stat(filePath,function(err,stat){如果(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/ba/cletindex=0;(functionnext(){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('删除成功')})深度预序(串行异步等待写入方法)//节点v10。在0.0+版本,fs模块提供了promise的写法constfs=require('fs').promises//如果在node10之前的版本可以引入第三方模块mzconstfs=require('mz/fs')用法一致https://www.npmjs.com/package/mzconstfs=require('fs').promisesconstpath=require('path')asyncfunctionrmdirAsync(filePath){letstat=awaitfs.stat(filePath)if(stat.isFile()){awaitfs.unlink(filePath)}else{letdirs=awaitfs.readdir(filePath)dirs=dirs.map(dir=>path.join(filePath,dir))letindex=0;(asyncfunctionnext(){if(index===dirs.length){awaitfs.rmdir(filePath)}else{awaitrmdirAsync(dirs[index++])awaitnext()}})()}}rmdirAsync('a').then(()=>{console.log('删除成功')},(err)=>{console.log('err',err)})深度预序(并行)深度预序(并行回调writing)constfs=require('fs').promisesconstpath=require('path')functionrmdir(filePath,callback){fs.stat(filePath,function(err,stat){if(err)返回控制台。log(err)if(stat.isFile()){fs.unlink(filePath,callback)}else{fs.readdir(filePath,function(err,dirs){if(err)returnconsole.log(err)//这里需要添加dirs.length的校验,否则如果length为0且不执行后面的forEach,则无法删除当前目录,无法执行回调if(dirs.length===0){fs.rmdir(文件路径,调用ck)}dirs=dirs.map(dir=>path.join(filePath,dir))//通过计数判断子目录是否删除letindex=0functiondone(){if(++index===dirs.length){fs.rmdir(filePath,callback)}}//什么是并行?a下有b和c两个目录,然后把b和c的删除同时推送到事件循环,使用for循环实现dirs.forEach(dir=>{//通过done回调控制js执行流程(LazyMan问题也是这样解决的)rmdir(dir,done)});})}})}rmdir('a',function(){console.log('删除成功')})深度前瞻(并行承诺写入)constfs=reqire('fs')constpath=require('path')functionrmdirPromise(filePath){returnnewPromise((resolve,reject)=>{fs.stat(filePath,function(err,stat){if(err)reject(err)if(stat.isFile()){fs.unlink(文件路径,函数(错误){如果(错误)拒绝(错误)解决()})}else{fs.readdir(文件路径,函数(错误,目录){如果(错误)拒绝(错误)目录=dirs.map(目录=>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写入)constfs=require('fs').promisesconstpath=require('path')asyncfunctionrmdirAsync(filePath){letstat=awaitfs.stat(filePath)if(stat.isFile()){awaitfs.unlink(filePath)}else{letdirs=awaitfs.readdir(filePath)dirs=dirs.map(dir=>rmdirAsync(path.join(filePath,dir)))awaitPromise.all(dirs)awaitfs.rmdir(filePath)}}rmdirAsync('a').then(()=>{console.log('删除成功')})