Is node.js rmdir recursive ? Will it work on non empty directories?

后端 未结 22 1356
清歌不尽
清歌不尽 2021-01-31 13:41

The documentation for fs.rmdir is very short and doesn\'t explain the behavior of rmdir when the directory is not empty.

Q: What happens if I try to use

相关标签:
22条回答
  • 2021-01-31 14:01

    This function will recursively delete a directory or file that you specify, synchronously:

    var path = require('path');
    
    function deleteRecursiveSync(itemPath) {
        if (fs.statSync(itemPath).isDirectory()) {
            _.each(fs.readdirSync(itemPath), function(childItemName) {
                deleteRecursiveSync(path.join(itemPath, childItemName));
            });
            fs.rmdirSync(itemPath);
        } else {
            fs.unlinkSync(itemPath);
        }
    }
    

    I have not tested this function's behavior if:

    • the item does not exist, or
    • the item cannot be deleted (such as due to a permissions issue).
    0 讨论(0)
  • 2021-01-31 14:03

    Although using a third-party library for such a thing I could not come up with a more elegant solution. So I ended up using the npm-module rimraf.

    Install it

    npm install rimraf
    

    Or install it and save to 'package.json' (other save options can be found in the npm-install docs)

    npm install --save rimraf
    

    Then you can do the following:

    rmdir = require('rimraf');
    rmdir('some/directory/with/files', function(error){});
    

    Or in Coffeescript:

    rmdir = require 'rimraf'
    rmdir 'some/directory/with/files', (error)->
    
    0 讨论(0)
  • 2021-01-31 14:03

    Here is an asynchronous recursive version that works with promises. I use the 'Q' library but anyone will do with a few changes (eg the 'fail' function).

    To make use of it, we must make a few simple wrappers around some core Node functions, namely fs.stat, fs.readdir, fs.unlink and fs.rmdir to make them promise-friendly.

    Here they are:

    function getStat(fpath) {
      var def = Q.defer();
      fs.stat(fpath, function(e, stat) {
        if (e) { def.reject(); } else { def.resolve(stat); }
      });
      return def.promise;
    }
    
    function readdir(dirpath) {
      var def = Q.defer();
      fs.readdir(dirpath, function(e, files) {
        if (e) { def.reject(e); } else { def.resolve(files); }
      });
      return def.promise;
    }
    
    function rmFile(fpath) {
      var def = Q.defer();
      fs.unlink(fpath, function(e) { if(e) { def.reject(e); } else { def.resolve(fpath); }});
      return def.promise;
    }
    
    function rmDir(fpath) {
      var def = Q.defer(); 
      fs.rmdir(fpath, function(e) { if(e) { def.reject(e); } else { def.resolve(fpath); }});
      return def.promise;
    }
    

    So here is the recursive rm function:

    var path = require('path');
    
    function recursiveDelete(fpath) {
      var def = Q.defer();
    
      getStat(fpath)
      .then(function(stat) {
        if (stat.isDirectory()) {
          return readdir(fpath)
          .then(function(files) {
            if (!files.length) { 
              return rmDir(fpath);
            } else {
              return Q.all(files.map(function(f) { return recursiveDelete(path.join(fpath, f)); }))
              .then(function() { return rmDir(fpath); });
            }
          }); 
        } else {
          return rmFile(fpath);
        }
      })
      .then(function(res) { def.resolve(res); })
      .fail(function(e) { def.reject(e); })
      .done();
      return def.promise;
    }
    
    0 讨论(0)
  • 2021-01-31 14:07

    Surprisingly verbose and bad answers here...

    To delete a non-empty directory on most systems:

    import * as cp from 'child_process';
    
    const dir = '/the/dir/to/remove';
    
    const k = cp.spawn('bash');
    
    k.stdin.end(`rm -rf "${dir}"`);
    
    k.once('exit', code => {
       // check the exit code
       // now you are done
    });
    

    this will work on MacOS and Linux, but it might not work on some Windows OS.

    0 讨论(0)
提交回复
热议问题