删除不是空的目录

在我的Node应用程序中,我需要删除一个有一些文件的目录,但是fs.rmdir只能在空目录下工作。 我怎样才能做到这一点?

有一个叫做rimraf的模块( https://npmjs.org/package/rimraf )。 它提供了与rm -Rf相同的function

基本用法:

 var rimraf = require('rimraf'); rimraf('/some/directory', function () { console.log('done'); }); 

同步删除文件夹

 var fs = require('fs'); var deleteFolderRecursive = function(path) { if (fs.existsSync(path)) { fs.readdirSync(path).forEach(function(file, index){ var curPath = path + "/" + file; if (fs.lstatSync(curPath).isDirectory()) { // recurse deleteFolderRecursive(curPath); } else { // delete file fs.unlinkSync(curPath); } }); fs.rmdirSync(path); } }; 

大部分使用fs和Node.js的人都希望函数接近处理文件的“Unix方式”。 我正在使用fs-extra来带来所有酷炫的东西:

fs-extra包含了不包含在vanilla Node.js fs包中的方法。 如mkdir -p,cp -r和rm -rf。

更好的是, fs-extra是原生fs的替代品。 fs中的所有方法都是未修改的并附加到它。 这意味着你可以用fs-extrareplacefs:

 // this can be replaced var fs = require('fs') // by this var fs = require('fs-extra') 

我写了这个函数叫做删除文件夹。 它将recursion删除位置中的所有文件和文件夹。 它需要的唯一软件包是asynchronous的。

 var async = require('async'); function removeFolder(location, next) { fs.readdir(location, function (err, files) { async.each(files, function (file, cb) { file = location + '/' + file fs.stat(file, function (err, stat) { if (err) { return cb(err); } if (stat.isDirectory()) { removeFolder(file, cb); } else { fs.unlink(file, function (err) { if (err) { return cb(err); } return cb(); }) } }) }, function (err) { if (err) return next(err) fs.rmdir(location, function (err) { return next(err) }) }) }) } 

这里是@ SharpCoder答案的asynchronous版本

 const fs = require('fs'); const path = require('path'); function deleteFile(dir, file) { return new Promise(function (resolve, reject) { var filePath = path.join(dir, file); fs.lstat(filePath, function (err, stats) { if (err) { return reject(err); } if (stats.isDirectory()) { resolve(deleteDirectory(filePath)); } else { fs.unlink(filePath, function (err) { if (err) { return reject(err); } resolve(); }); } }); }); }; function deleteDirectory(dir) { return new Promise(function (resolve, reject) { fs.access(dir, function (err) { if (err) { return reject(err); } fs.readdir(dir, function (err, files) { if (err) { return reject(err); } Promise.all(files.map(function (file) { return deleteFile(dir, file); })).then(function () { fs.rmdir(dir, function (err) { if (err) { return reject(err); } resolve(); }); }).catch(reject); }); }); }); }; 

我修改了@oconnecp的答案( https://stackoverflow.com/a/25069828/3027390

使用path.join来获得更好的跨平台体验。 所以,不要忘记要求。

 var path = require(path); 

也更名为rimraffunction;)

 /** * 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); } } 

我到达这里的时候,试图克服gulp ,我正在写作进一步到达。

  • gulp-rimraf gulp-clean弃用的gulp-rimraf
  • gulp-rimraf弃用了delete-files-folders

当你想使用del删除文件和文件夹,你应该追加/**recursion删除。

 gulp.task('clean', function () { return del(['some/path/to/delete/**']); }); 

只需使用rmdir模块 ! 这很容易和简单。

另一种select是使用提供fs-extra模块的promisified版本的fs-promise模块

你可以这样写:

 const { remove, mkdirp, writeFile, readFile } = require('fs-promise') const { join, dirname } = require('path') async function createAndRemove() { const content = 'Hello World!' const root = join(__dirname, 'foo') const file = join(root, 'bar', 'baz', 'hello.txt') await mkdirp(dirname(file)) await writeFile(file, content) console.log(await readFile(file, 'utf-8')) await remove(join(__dirname, 'foo')) } createAndRemove().catch(console.error) 

注意:asynchronous/等待需要最近的nodejs版本(7.6+)

我希望有一种方法可以做到这一点,没有额外的模块的东西如此微不足道,常见,但这是我能想到的最好的。

更新:现在应该在Windows(testing的Windows 10)上工作,并且还应该在Linux / Unix / BSD / Mac系统上工作。

 const execSync = require("child_process").execSync, fs = require("fs"), os = require("os"); let removeDirCmd, theDir; removeDirCmd = os.platform() === 'win32' ? "rmdir /s /q " : "rm -rf "; theDir = __dirname + "/../web-ui/css/"; // WARNING: Do not specify a sinle file as the windows rmdir command will error. if (fs.existsSync(theDir)) { console.log(' removing the ' + theDir + ' directory.'); execSync(removeDirCmd + '"' + theDir + '"', function (err) { console.log(err); }); } 

随着承诺的使用, asynchronous删除目录..

 MyObject.prototype.removeDir = function (path) { var executor = (resolve, reject)=> { var relativePath = ""; //lets read the directory first fs.readdir(path, (err, files)=> { let fLen = files.length; //if this directory doesn't contain any file lets just delete it and then resolve or reject.. //depending on whether there is an error or not if (fLen === 0) { fs.rmdir(path, (err)=> { if (err) return reject(err); else return resolve(true) }); } //remember its asynchronous... so the loop runs without a block for (let i = 0; i < fLen; i++) { //append each fileName to the directory path to get is relativePath relativePath = path + "/" + files[i]; //we also need to be sure the file is indeed a file or a directory fs.stat(relativePath, (err, stats)=> { if (err) { console.log(err); return err } if (stats.isFile()) { fs.unlink(relativePath, (err)=> { if (err) return reject(err); console.log("fs.unlink"); //if we have gotten to the last file within the directory we can now delete it if (i === fLen - 1) { fs.rmdir(path, (err)=> { if (err) return reject(err); else return resolve(true) }); } }); } //so if there is a directory within this directory we should delete it as well else if (stats.isDirectory()) { //recursively deletes directory within a directory this.removeDir(relativePath); } console.log("fs.Stat"); }); } }); }; return new Promise(executor); };