在我的节点应用程序中,我需要删除一个目录,其中有一些文件,但fs。Rmdir只适用于空目录。我该怎么做呢?
当前回答
方法删除非空目录
rmdir(path,{recursive:true,force:true}
rm(path,{recursive:true,force:true}
将工作
代码片段:
const fsp = require("fs/promises");
deleteDirRecursively("./b");
removeRecursively("./BCD/b+");
async function deleteDirRecursively(dirPath) {
try {
// fsPromises.rmdir() on a file (not a directory) results in the promise being rejected
// with an ENOENT error on Windows and an ENOTDIR error on POSIX.
// To get a behavior similar to the rm -rf Unix command,
// use fsPromises.rm() with options { recursive: true, force: true }.
//will not thorw error if dir is empty
//will thow error if dir is not present
await fsp.rmdir(dirPath, { recursive: true, force: true });
console.log(dirPath, "deleted successfully");
} catch (err) {
console.log(err);
}
async function removeRecursively(path) {
try {
//has ability to remove both file and dir
//can delete dir recursively and forcefully
//will delete an empty dir.
//will remove all the contents of a dir.
// the only difference between rmdir and rm is that rmdir can only delete dir's
await fsp.rm(path, { recursive: true, force: true });
console.log(path, "deleted successfully");
} catch (err) {
console.log(err);
}
}
其他回答
@SharpCoder的答案使用fs.promises的异步版本:
const fs = require('fs');
const afs = fs.promises;
const deleteFolderRecursive = async path => {
if (fs.existsSync(path)) {
for (let entry of await afs.readdir(path)) {
const curPath = path + "/" + entry;
if ((await afs.lstat(curPath)).isDirectory())
await deleteFolderRecursive(curPath);
else await afs.unlink(curPath);
}
await afs.rmdir(path);
}
};
大多数在Node.js中使用fs的人都希望函数能够接近“Unix方式”来处理文件。我使用fs-extra来带来所有很酷的东西:
fs-extra包含了普通Node.js中不包含的方法 fs包。如mkdir -p、cp -r、rm -rf等。
更好的是,fs-extra是本地fs的替代品。fs中的所有方法都是未修改的,并附加到它。 这意味着你可以用fs-extra替换fs:
// this can be replaced
const fs = require('fs')
// by this
const fs = require('fs-extra')
然后你可以这样删除一个文件夹:
fs.removeSync('/tmp/myFolder');
//or
fs.remove('/tmp/myFolder', callback);
我修改后的答案来自@oconnecp (https://stackoverflow.com/a/25069828/3027390)
使用路径。加入可以获得更好的跨平台体验。 所以,不要忘记要求它。
var path = require('path');
也将函数重命名为rimraf;)
/**
* Remove directory recursively
* @param {string} dir_path
* @see https://stackoverflow.com/a/42505874/3027390
*/
function rimraf(dir_path) {
if (fs.existsSync(dir_path)) {
fs.readdirSync(dir_path).forEach(function(entry) {
var entry_path = path.join(dir_path, entry);
if (fs.lstatSync(entry_path).isDirectory()) {
rimraf(entry_path);
} else {
fs.unlinkSync(entry_path);
}
});
fs.rmdirSync(dir_path);
}
}
一种快速而肮脏的方法(可能用于测试)可能是直接使用exec或spawn方法调用OS调用来删除目录。阅读更多NodeJs child_process。
let exec = require('child_process').exec
exec('rm -Rf /tmp/*.zip', callback)
缺点是:
你依赖于底层的操作系统,即相同的方法可以在unix/linux中运行,但可能不能在windows中运行。 您不能根据条件或错误劫持流程。您只需将任务交给底层操作系统,并等待退出码返回。
好处:
这些流程可以异步运行。 可以监听命令的输出/错误,因此命令输出不会丢失。如果操作未完成,请检查错误码后重试。
事实上的包是rimraf,但这里是我的小异步版本:
const fs = require('fs')
const path = require('path')
const Q = require('q')
function rmdir (dir) {
return Q.nfcall(fs.access, dir, fs.constants.W_OK)
.then(() => {
return Q.nfcall(fs.readdir, dir)
.then(files => files.reduce((pre, f) => pre.then(() => {
var sub = path.join(dir, f)
return Q.nfcall(fs.lstat, sub).then(stat => {
if (stat.isDirectory()) return rmdir(sub)
return Q.nfcall(fs.unlink, sub)
})
}), Q()))
})
.then(() => Q.nfcall(fs.rmdir, dir))
}
推荐文章
- ReferenceError: description没有定义NodeJs
- 将一个二进制的NodeJS Buffer转换为JavaScript的ArrayBuffer
- AngularJS只适用于单页应用程序吗?
- 如何在vue-cli项目中更改端口号
- 同步和异步编程(在node.js中)的区别是什么?
- 如何编辑通过npm安装的节点模块?
- “node_modules”文件夹应该包含在git存储库中吗
- 使用package.json在全局和本地安装依赖项
- this.libOptions.parse不是一个函数
- 对嵌套文件夹运行npm install的最好方法是什么?
- 节点Multer异常字段
- 很好的初学者教程socket.io?
- CALL_AND_RETRY_LAST分配失败-进程内存不足
- 在Ubuntu上安装Node.js
- 使用express.js代理