【问题标题】:Remove directory which is not empty删除非空目录
【发布时间】:2013-08-05 20:11:34
【问题描述】:

在我的 Node 应用程序中,我需要删除一个包含一些文件的目录,但 fs.rmdir 仅适用于空目录。我该怎么做?

【问题讨论】:

  • 简而言之:fs.readdir(dirPath) 用于文件夹中的路径数组,遍历 fs.unlink(filename) 以删除每个文件,最后通过 fs.rmdir(dirPath) 删除现在为空的文件夹。如需递归,请查看fs.lstat(filename).isDirectory()
  • fs.rm(dirPath, { recursive: true, force: true }) - 见nodejs.org/api/fs.html#fs_fspromises_rm_path_options(注意,我使用的是rm而不是rmdir

标签: node.js filesystems


【解决方案1】:

从 Node.js 14.14.0 开始,推荐使用fs.rmSync

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

【讨论】:

  • @anneb 如果您使用的是旧版本的 Node.js (recursive: true 并删除非空文件夹而不抱怨。
  • 从节点 v13.0.1 开始,递归删除仍处于试验阶段
  • 函数签名其实是fs.rmdir(path[, options], callback)或者fs.rmdirSync(path[, options])
  • 递归 rmdir 在内部使用 rimraf,如拉取请求 github.com/nodejs/node/pull/29168/files
  • 请注意recursive选项is deprecatedv14.14.0。 API 文档建议改用 fs.rm(path, { recursive: true, force: true })
【解决方案2】:

有一个名为rimraf (https://npmjs.org/package/rimraf) 的模块。它提供与rm -Rf相同的功能

异步用法:

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

同步使用:

rimraf.sync("/some/directory");

【讨论】:

  • 这可以通过 NodeJS 核心库轻松完成,为什么要安装未维护的 3rd 方包?
  • @EmettSpeer 你什么时候说“轻松完成”?在下面的答案中自行编写类似deleteFolderRecursive 的函数?
  • "但即使使用下面的功能也比在系统中添加不需要的包更好。"我强烈反对。您毫无理由地第 1900 万次重新发明轮子,并冒着在此过程中引入错误或安全漏洞的风险。至少这是在浪费时间。 Inb4 “如果他们丢掉了包怎么办”:万一包从 npm 注册表中删除,你总是可以用你自己的 then. 替换它。在你之前包扎你的头是没有意义的打破它。
  • 现在您可以使用 del (npmjs.com/package/del) 代替 @rimraf
  • 您现在可以使用recursive 选项:stackoverflow.com/a/57866165/6269864
【解决方案3】:

同步删除文件夹

    const fs = require('fs');
    const Path = require('path');

    const deleteFolderRecursive = function (directoryPath) {
    if (fs.existsSync(directoryPath)) {
        fs.readdirSync(directoryPath).forEach((file, index) => {
          const curPath = path.join(directoryPath, file);
          if (fs.lstatSync(curPath).isDirectory()) {
           // recurse
            deleteFolderRecursive(curPath);
          } else {
            // delete file
            fs.unlinkSync(curPath);
          }
        });
        fs.rmdirSync(directoryPath);
      }
    };

【讨论】:

  • 可能想要添加一些检查,以确保您不会意外地在“/”上运行它。例如,传递一个空路径和文件中的拼写错误可能导致 curPath 成为根目录。
  • 更健壮的实现:将 var curPath = path + "/" + file; 替换为 var curPath = p.join(path, file);,前提是您包含路径模块:var p = require("path")
  • Windows 有\斜线,所以path.join(dirpath, file) 应该比path + "/" + file
  • 由于一个滴答时间内的操作太多,您可能会收到“超出最大调用堆栈大小”的代码。 @Walf 如果您运行控制台应用程序,您有 1 个客户端,而不是更多。因此,在这种情况下,无需对控制台应用程序使用异步
  • 我收到“错误:ENOTEMPTY:目录不为空”
【解决方案4】:

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

fs-extra 包含原生 Node.js 中未包含的方法 fs 包。如 mkdir -p、cp -r 和 rm -rf。

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

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

【讨论】:

  • 你需要的同步版本removeSync('/tmp/myFolder')
【解决方案5】:

从 Node v14(2020 年 10 月)开始,fs 模块具有支持递归、非空目录取消链接的 fs.rmrs.rmSync

https://nodejs.org/docs/latest-v14.x/api/fs.html#fs_fs_rm_path_options_callback

所以你现在可以这样做:

const fs = require('fs');
fs.rm('/path/to/delete', { recursive: true }, () => console.log('done'));

或:

const fs = require('fs');
fs.rmSync('/path/to/delete', { recursive: true });
console.log('done');

【讨论】:

  • 对不起,我快速错误地投了反对票。我想纠正我的错误……但在编辑/更新答案之前我不能取消投票。
【解决方案6】:

我从@oconnecp (https://stackoverflow.com/a/25069828/3027390) 修改后的回答

使用 path.join 以获得更好的跨平台体验。 所以,别忘了要求它。

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

【讨论】:

    【解决方案7】:

    我通常不会复活旧线程,但这里有很多大量在流失,并且没有 rimraf 的答案,这些对我来说似乎都过于复杂。

    首先在现代 Node (>= v8.0.0) 中,您可以仅使用节点核心模块来简化流程,完全异步,并在五行函数中同时并行化文件的取消链接,并且仍然保持可读性:

    const fs = require('fs');
    const path = require('path');
    const { promisify } = require('util');
    const readdir = promisify(fs.readdir);
    const rmdir = promisify(fs.rmdir);
    const unlink = promisify(fs.unlink);
    
    exports.rmdirs = async function rmdirs(dir) {
      let entries = await readdir(dir, { withFileTypes: true });
      await Promise.all(entries.map(entry => {
        let fullPath = path.join(dir, entry.name);
        return entry.isDirectory() ? rmdirs(fullPath) : unlink(fullPath);
      }));
      await rmdir(dir);
    };
    

    另一方面,path traversal attacks 的守卫不适合此功能,因为

    1. 它超出了基于 Single Responsibility Principle 的范围。
    2. 应该由调用者处理而不是这个函数。这类似于命令行rm -rf,因为它接受一个参数,并允许用户在被要求时使用rm -rf /。保护rm 程序本身不是脚本的责任。
    3. 此函数无法确定此类攻击,因为它没有参考框架。这也是调用者的责任,调用者将拥有意图的上下文,这将为它提供一个参考来比较路径遍历。
    4. 符号链接不是问题,因为.isDirectory() 是符号链接的false,并且未链接到不递归。

    最后但并非最不重要的一点是,如果在此递归运行时恰好在此脚本之外此脚本中取消链接或删除其中一个条目,则递归可能会出错。由于这种情况在大多数环境中并不常见,因此很可能会被忽略。但是,如果需要(对于某些边缘情况),这个问题可以通过这个稍微复杂的示例来缓解:

    exports.rmdirs = async function rmdirs(dir) {
      let entries = await readdir(dir, { withFileTypes: true });
      let results = await Promise.all(entries.map(entry => {
        let fullPath = path.join(dir, entry.name);
        let task = entry.isDirectory() ? rmdirs(fullPath) : unlink(fullPath);
        return task.catch(error => ({ error }));
      }));
      results.forEach(result => {
        // Ignore missing files/directories; bail on other errors
        if (result && result.error.code !== 'ENOENT') throw result.error;
      });
      await rmdir(dir);
    };
    

    编辑:使isDirectory() 成为一个函数。最后删除实际目录。修复缺少的递归。

    【讨论】:

    • 这是一个非常巧妙的解决方案。关于第二个代码示例的问题:您没有在您的Promise.all(…) 上调用await;这是故意的吗?似乎在其当前状态下results.forEach 将迭代承诺,而代码期望迭代结果。我错过了什么吗?
    • @Tony 你是对的,这是一个错字/错误。好收获!
    • 也许先检查以确保目录存在?类似if (!fs.existsSync(dir)) return
    • @GTPV 为什么?这增加了这个函数的责任。 readdir 应该会抛出错误。如果你rmdir non-existing-dir 退出代码是一个错误。消费者有责任尝试/捕捉。在使用 fs 函数时,这与 Node 文档中描述的方法相同。他们希望您尝试/捕捉并查看错误的code 以确定要做什么。额外的检查会引入竞争条件。
    • 我绝对明白你的意思。尽管直觉上我希望尝试删除不存在的文件夹会成功,因为它只会什么都不做。如果使用fs.exists 的同步版本,则没有竞争条件。附言这是一个很好的解决方案。
    【解决方案8】:

    这是@SharpCoder's answer的异步版本

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

    【讨论】:

      【解决方案9】:

      我写了这个叫做删除文件夹的函数。它将递归删除某个位置的所有文件和文件夹。它唯一需要的包是 async。

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

      【讨论】:

      • 这个想法实际上是不要编写自己的代码,如果它已经由其他人编写。更好的方法是使用 rimraf 或 fs-extra 或任何其他节点模块来为您完成工作。
      • 是的,编写自己的代码很糟糕,因为使用数十个 3rd 方模块进行相对琐碎的操作从未被证明在大规模应用程序中有任何缺点。
      【解决方案10】:

      [编辑:使用 node.js v15.5.0]

      刚刚尝试使用此处发布的一些解决方案,我遇到了以下弃用警告:

      (node:13202) [DEP0147] 弃用警告:在未来的版本中 Node.js, fs.rmdir(path, { recursive: true }) 如果 path 会抛出 不存在或者是一个文件。使用 fs.rm(path, { recursive: true, force: true }) 代替

      fs.rm(path, { recursive: true, force: true }); 可以很好地工作,如果您想使用阻止版本,请使用 fs.rmSync(path, { recursive: true, force: true });

      【讨论】:

      • 您使用的是哪个版本的节点?当我尝试使用fs.rm时,我得到TypeError: fs.rm is not a function
      • 我正在使用 v15.5.0
      • 有道理。我正在运行 v12,看起来 fs.rm 和 fs.rmSync 是在 v14 中添加的
      • 这太完美了!它可以无缝运行,并且不需要安装任何第 3 方依赖项。
      【解决方案11】:

      如果您使用的是 node 8+,想要异步且不想要外部依赖,这里是 async/await 版本:

      const path = require('path');
      const fs = require('fs');
      const util = require('util');
      
      const readdir = util.promisify(fs.readdir);
      const lstat = util.promisify(fs.lstat);
      const unlink = util.promisify(fs.unlink);
      const rmdir = util.promisify(fs.rmdir);
      
      const removeDir = async (dir) => {
          try {
              const files = await readdir(dir);
              await Promise.all(files.map(async (file) => {
                  try {
                      const p = path.join(dir, file);
                      const stat = await lstat(p);
                      if (stat.isDirectory()) {
                          await removeDir(p);
                      } else {
                          await unlink(p);
                          console.log(`Removed file ${p}`);
                      }
                  } catch (err) {
                      console.error(err);
                  }
              }))
              await rmdir(dir);
              console.log(`Removed dir ${dir}`);
          } catch (err) {
            console.error(err);
          }
      }
      

      【讨论】:

        【解决方案12】:
        const fs = require("fs");
        fs.rmdir("./test", { recursive: true }, (err) => {
          if (err) {
            console.error(err);
          }
        });
        
        

        提供recursive: true 选项。它将递归删除给定路径的所有文件和目录。 (假设test 是根目录。)

        【讨论】:

          【解决方案13】:

          我在尝试通过gulp 克服时到达这里,我正在写信以求更进一步。

          当您想使用del删除文件和文件夹时,您应该附加/**进行递归删除。

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

          【讨论】:

            【解决方案14】:

            在最新版本的 Node.js(12.10.0 或更高版本)中,rmdir 样式函数 fs.rmdir()fs.rmdirSync()fs.promises.rmdir() 有一个新的实验选项 recursive,它允许删除非空目录,例如

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

            GitHub上相关PR:https://github.com/nodejs/node/pull/29168

            【讨论】:

              【解决方案15】:

              使用 fs.promises 的 @SharpCoder's answer 的异步版本:

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

              【讨论】:

                【解决方案16】:

                根据fs documentationfsPromises 目前在实验基础上提供了recursive 选项,至少在我自己在 Windows 上的情况下,它会删除目录和其中的任何文件。

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

                recursive: true 会删除 Linux 和 MacOS 上的文件吗?

                【讨论】:

                • 这是截至 2020 年的最佳答案。它在 MacOS 上运行
                【解决方案17】:

                说明

                从 Node.js v14 开始,我们现在可以使用 require("fs").promises.rm 函数通过 Promise 删除文件。第一个参数将是要删除的文件或文件夹(甚至是不存在的文件或文件夹)。您可以在第二个参数的对象中使用 recursiveforce 选项来模拟带有 -rf 选项的 rm Shell 命令实用程序的行为。

                示例

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

                Node.js v14 Documentation

                Mozilla Developer Promises Documentation

                rm command manual page

                【讨论】:

                  【解决方案18】:
                  return new Promise((resolve, reject) => {
                    const fs = require("fs");
                    // directory path
                    const dir = "your/dir";
                  
                    // delete directory recursively <------
                    fs.rmdir(dir, { recursive: true }, (err) => {
                      if (err) {
                        reject(err);
                      }
                      resolve(`${dir} is deleted!`);
                    });
                  });
                  

                  【讨论】:

                    【解决方案19】:

                    here所写。

                    要获得类似于rm -rf Unix 命令的行为,请使用fs.rm() 和选项{ recursive: true, force: true }

                    【讨论】:

                      【解决方案20】:

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

                      【讨论】:

                      • 对每一小段代码都使用一个模块并不总是一个好主意。例如,如果您必须创建许可协议,这会产生真正的痛苦。
                      • 您需要添加代码示例以使您的答案更有趣
                      【解决方案21】:

                      一种快速而肮脏的方法(可能用于测试)可能是直接使用execspawn方法调用操作系统调用以删除目录。阅读更多NodeJs child_process

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

                      缺点是:

                      1. 您依赖于底层操作系统,即相同的方法可以在 unix/linux 中运行,但可能不会在 Windows 中运行。
                      2. 您不能在条件或错误的情况下劫持进程。您只需将任务交给底层操作系统并等待退出代码返回即可。

                      好处:

                      1. 这些进程可以异步运行。
                      2. 您可以监听命令的输出/错误,因此命令输出不会丢失。如果操作未完成,您可以检查错误代码并重试。

                      【讨论】:

                      • 非常适合您编写脚本并且不想安装依赖项,因为您将在删除所有文件后 30 秒内删除此脚本!
                      • 总有办法搞砸和删除根文件系统。在这种情况下,OP 可以删除 -f 标志以确保安全,或者确保在键入时他/她不会删除所有内容。 exec + rm 是 node 中一个有效且有用的命令,我在测试过程中经常使用它。
                      【解决方案22】:

                      事实上的包是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))
                      }
                      
                      

                      【讨论】:

                        【解决方案23】:

                        2020 年更新

                        从版本 12.10.0 recursiveOption 已添加选项。

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

                        所以你会做同步:

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

                        或异步:

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

                        【讨论】:

                          【解决方案24】:

                          超高速和防故障

                          您可以使用 lignator 包 (https://www.npmjs.com/package/lignator),它比任何异步代码(例如 rimraf)都更快,并且更防故障(尤其是在 Windows 中,文件删除不是即时的,文件可能被其他人锁定)进程)。

                          Windows 上 4,36 GB 的数据、28042 个文件、4217 个文件夹在 15 秒内删除,而 rimraf 在旧硬盘上的 60 秒

                          const lignator = require('lignator');
                          
                          lignator.remove('./build/');
                          

                          【讨论】:

                            【解决方案25】:

                            将文件夹与文件同步删除或仅删除一个文件。

                            我既不是给予者也不是贡献者,但我找不到解决这个问题的好方法,我必须找到自己的方法......所以我希望你会喜欢它:)

                            非常适合我使用任意数量的嵌套目录和子目录。递归函数时注意“this”的范围,您的实现可能会有所不同。在我的情况下,这个函数停留在另一个函数的返回中,这就是我用这个调用它的原因。

                                const fs = require('fs');
                            
                                deleteFileOrDir(path, pathTemp = false){
                                        if (fs.existsSync(path)) {
                                            if (fs.lstatSync(path).isDirectory()) {
                                                var files = fs.readdirSync(path);
                                                if (!files.length) return fs.rmdirSync(path);
                                                for (var file in files) {
                                                    var currentPath = path + "/" + files[file];
                                                    if (!fs.existsSync(currentPath)) continue;
                                                    if (fs.lstatSync(currentPath).isFile()) {
                                                        fs.unlinkSync(currentPath);
                                                        continue;
                                                    }
                                                    if (fs.lstatSync(currentPath).isDirectory() && !fs.readdirSync(currentPath).length) {
                                                        fs.rmdirSync(currentPath);
                                                    } else {
                                                        this.deleteFileOrDir(currentPath, path);
                                                    }
                                                }
                                                this.deleteFileOrDir(path);
                                            } else {
                                                fs.unlinkSync(path);
                                            }
                                        }
                                        if (pathTemp) this.deleteFileOrDir(pathTemp);
                                    }
                            

                            【讨论】:

                              【解决方案26】:

                              2020 年答案

                              如果您想在 npm 脚本中执行此操作,如果您使用命令 npx

                              ,则无需预先安装任何 3rd 方包

                              例如,如果您想在运行 npm run clean 时删除文件夹 dist.cache,那么只需将此命令添加到您的 package.json

                              {
                                "scripts": {
                                  "clean": "npx rimraf dist .cache"
                                }
                              }
                              

                              它适用于任何操作系统

                              【讨论】:

                              • 这还不需要安装rimraf依赖吗?
                              • @trebor no,因为我们使用 npx 运行它,这允许在不安装它的情况下运行一个包
                              • @JuanmaMenendez 错了。来自 npx 的docs: "默认情况下,npx 会检查 是否存在于 $PATH 或本地项目二进制文件中,然后执行。如果没有找到 ,则会安装它在执行之前。” 这似乎很明显,你将如何执行不存在的东西? npx 的优点是,它会尝试在你的 PATH 和你的项目中本地找到你的命令,并且只有在找不到它时才进行安装。
                              • 不过,它不会将包添加到项目中。但尽管如此,它必须将它安装在某个地方。因此,对于主要打算从构建脚本或命令行调用的软件包,我更喜欢全局安装它们,因此只需一次安装,它们就可以在任何地方使用
                              • @derpirscher 'npx' 在幕后,如果需要的话,临时安装软件包,但对我们来说这是透明的。使用“npx”,我们不需要在 package.json 中添加我们想要使用的包。我们,执行它。
                              【解决方案27】:

                              另一种选择是使用fs-promise 模块,它提供了fs-extra 模块的承诺版本

                              你可以这样写:

                              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)
                              

                              注意:async/await 需要最新的 nodejs 版本(7.6+)

                              【讨论】:

                                【解决方案28】:

                                我希望有一种方法可以做到这一点,而无需额外的模块来处理如此微不足道和常见的事情,但这是我能想到的最好的方法。

                                更新: 现在应该可以在 Windows 上运行(经过测试的 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 single 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);
                                    });
                                }
                                

                                【讨论】:

                                • 如果你想要一个单独的模块,也许 fs-extra 是要走的路。
                                • 这种方法非常危险。 shell 命令的字符串连接,尤其是在没有转义的情况下,会引发代码执行漏洞等。如果要使用 rmdir,请使用不调用 shell 的 child_process.execFile,而是显式传递参数。
                                • @nevyn 我会试一试,如果可行,我会更新我的答案。
                                • 总是不喜欢使用第三方!谢谢!
                                • 除此之外,这种方法相当慢。 Nodejs 原生 api 更快。
                                【解决方案29】:

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

                                它异步执行所有操作。

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

                                【讨论】:

                                  【解决方案30】:
                                  const fs = require("fs")
                                  const path = require("path")
                                  
                                  let _dirloc = '<path_do_the_directory>'
                                  
                                  if (fs.existsSync(_dirloc)) {
                                    fs.readdir(path, (err, files) => {
                                      if (!err) {
                                        for (let file of files) {
                                          // Delete each file
                                          fs.unlinkSync(path.join(_dirloc, file))
                                        }
                                      }
                                    })
                                    // After the 'done' of each file delete,
                                    // Delete the directory itself.
                                    if (fs.unlinkSync(_dirloc)) {
                                      console.log('Directory has been deleted!')
                                    }
                                  }
                                  

                                  【讨论】:

                                  • 我认为这样的东西应该适用于嵌套目录。
                                  • 是的,嵌套目录和非嵌套目录都可以
                                  猜你喜欢
                                  • 2012-05-31
                                  • 2016-10-16
                                  • 2010-12-11
                                  • 1970-01-01
                                  • 2010-12-06
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多