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

后端 未结 22 1359
清歌不尽
清歌不尽 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 13:43

    A neat synchronous version of rmdirSync.

    /** 
     * use with try ... catch ...
     * 
     * If you have permission to remove all file/dir
     * and no race condition and no IO exception...
     * then this should work 
     *
     * uncomment the line 
     *   if(!fs.exists(p)) return 
     * if you care the inital value of dir, 
     * 
     */
    var fs = require('fs')
    var path = require('path')
    
    function rmdirSync(dir,file){
      var p = file? path.join(dir,file):dir;
      // if(!fs.exists(p)) return 
      if(fs.lstatSync(p).isDirectory()){
        fs.readdirSync(p).forEach(rmdirSync.bind(null,p))
        fs.rmdirSync(p)
      }
      else fs.unlinkSync(p)
    }
    

    And a parallel IO, asynchronous version of rmdir. (faster)

    /**
     * NOTE: 
     * 
     * If there are no error, callback will only be called once.
     * 
     * If there are multiple errors, callback will be called 
     * exactly as many time as errors occur. 
     * 
     * Sometimes, this behavior maybe useful, but users 
     * should be aware of this and handle errors in callback. 
     * 
     */
    
    var fs = require('fs')
    var path = require('path')
    
    function rmfile(dir, file, callback){
      var p = path.join(dir, file)
      fs.lstat(p, function(err, stat){
        if(err) callback.call(null,err)
        else if(stat.isDirectory()) rmdir(p, callback)
        else fs.unlink(p, callback)
      })
    }
    
    function rmdir(dir, callback){
      fs.readdir(dir, function(err,files){
        if(err) callback.call(null,err)
        else if( files.length ){
          var i,j
          for(i=j=files.length; i--; ){
            rmfile(dir,files[i], function(err){
              if(err) callback.call(null, err)
              else if(--j === 0 ) fs.rmdir(dir,callback)
            })
          }
        }
        else fs.rmdir(dir, callback)
      })
    }
    

    Anyway, if you want a sequential IO, and callback be called exactly once (either success or with first error encountered). Replace this rmdir with the above. (slower)

    function rmdir(dir, callback){
      fs.readdir(dir, function(err,files){
        if(err) callback.call(null,err)
        else if( files.length ) rmfile(dir, files[0], function(err){
          if(err) callback.call(null,err)
          else rmdir(dir, callback)
        })
        else fs.rmdir(dir, callback)
      })
    }
    

    All of them depend ONLY on node.js and should be portable.

提交回复
热议问题