在我的节点应用程序中,我需要删除一个目录,其中有一些文件,但fs。Rmdir只适用于空目录。我该怎么做呢?


当前回答

这是一种使用promisify和两个帮助函数(to和toAll)来解决承诺的方法。

它以异步方式执行所有操作。

const fs = require('fs');
const { promisify } = require('util');
const to = require('./to');
const toAll = require('./toAll');

const readDirAsync = promisify(fs.readdir);
const rmDirAsync = promisify(fs.rmdir);
const unlinkAsync = promisify(fs.unlink);

/**
    * @author Aécio Levy
    * @function removeDirWithFiles
    * @usage: remove dir with files
    * @param {String} path
    */
const removeDirWithFiles = async path => {
    try {
        const file = readDirAsync(path);
        const [error, files] = await to(file);
        if (error) {
            throw new Error(error)
        }
        const arrayUnlink = files.map((fileName) => {
            return unlinkAsync(`${path}/${fileName}`);
        });
        const [errorUnlink, filesUnlink] = await toAll(arrayUnlink);
        if (errorUnlink) {
            throw new Error(errorUnlink);
        }
        const deleteDir = rmDirAsync(path);
        const [errorDelete, result] = await to(deleteDir);
        if (errorDelete) {
            throw new Error(errorDelete);
        }
    } catch (err) {
        console.log(err)
    }
}; 

其他回答

如果你更喜欢async/await,你可以使用fs/promises API。

const fs = require('fs/promises');

const removeDir = async (dirPath) => {
  await fs.rm(dirPath, {recursive: true});
}

如果您知道文件夹中单个文件的路径,并希望删除包含该文件的文件夹。

const fs = require('fs/promises');
const path = require('path');

const removeDir = async (filePath) => {
  const { dir } = path.parse(filePath);
  await fs.rm(dir, { recursive: true });
}

2020年更新

从12.10.0版本开始,为选项添加了recursiveOption。

注意,递归删除是实验性的。

所以你会做同步:

fs.rmdirSync(dir, {recursive: true});

或者async:

fs.rmdir(dir, {recursive: true});

我到达这里时,试图克服与大口,我正在写进一步达到。

对于gulp-rimraf,已弃用Gulp-clean Gulp-rimraf已弃用,支持delete-files-folders

当要使用del删除文件和文件夹时,应添加/**进行递归删除。

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

@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);
    }
};

一种快速而肮脏的方法(可能用于测试)可能是直接使用exec或spawn方法调用OS调用来删除目录。阅读更多NodeJs child_process。

let exec = require('child_process').exec
exec('rm -Rf /tmp/*.zip', callback)

缺点是:

你依赖于底层的操作系统,即相同的方法可以在unix/linux中运行,但可能不能在windows中运行。 您不能根据条件或错误劫持流程。您只需将任务交给底层操作系统,并等待退出码返回。

好处:

这些流程可以异步运行。 可以监听命令的输出/错误,因此命令输出不会丢失。如果操作未完成,请检查错误码后重试。