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


当前回答

根据fs文档,fsPromises目前在实验的基础上提供了递归选项,至少在我自己的Windows上,它删除了目录和其中的任何文件。

fsPromises.rmdir(path, {
  recursive: true
})

递归:true是否删除Linux和MacOS上的文件?

其他回答

这是一种使用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)
    }
}; 

解释

从Node.js v14开始,我们现在可以使用require("fs").promises。Rm函数使用promise删除文件。第一个参数是要删除的文件或文件夹(即使是不存在的文件或文件夹)。您可以在第二个参数的对象中使用递归和强制选项来模拟rm Shell命令实用程序的-rf选项的行为。

例子

"use strict";

require("fs").promises.rm("directory", {recursive: true, force: true}).then(() => {
  console.log("removed");
}).catch(error => {
  console.error(error.message);
});

See

Node.js v14文档

Mozilla开发者承诺文档

Rm命令手册

下面是@SharpCoder的答案的异步版本

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

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

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

缺点是:

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

好处:

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

//不使用任何第三方lib

const fs = require('fs');
var FOLDER_PATH = "./dirname";
var files = fs.readdirSync(FOLDER_PATH);
files.forEach(element => {
    fs.unlinkSync(FOLDER_PATH + "/" + element);
});
fs.rmdirSync(FOLDER_PATH);