28

I have searched the Nodejs Doc,But don't find relative API.

So I write the following code to determine whether the directory is empty directory.

var fs = require('fs');

function isEmptyDir(dirnane){
    try{
        fs.rmdirSync(dirname)
    }
    catch(err){
        return false;
    }
    fs.mkdirSync(dirname);
    return true
}

QUESTION:it look like some troublesome,there is better way to do it with nodejs?

kwoktung
  • 572
  • 1
  • 4
  • 12

3 Answers3

44

I guess I'm wondering why you don't just list the files in the directory and see if you get any files back?

fs.readdir(dirname, function(err, files) {
    if (err) {
       // some sort of error
    } else {
       if (!files.length) {
           // directory appears to be empty
       }
    }
});

You could, of course, make a synchronous version of this too.

This, of course, doesn't guarantee that there's nothing in the directory, but it does mean there are no public files that you have permission to see there.


Here's a promise version in a function form for newer versions of nodejs:

function isDirEmpty(dirname) {
    return fs.promises.readdir(dirname).then(files => {
        return files.length === 0;
    });
}
Ahmad Awais
  • 33,440
  • 5
  • 74
  • 56
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 1
    Reasonable, but a potentially serious performance hit (both time and memory) if there are a lot (i.e. potentially thousands+) of files in the directory. – user3570671 Apr 22 '19 at 16:10
  • @user3570671 - What else would you suggest? And, do you have any evidence that doing this on a directory with 1000 files would actually be a noticeable performance issue? – jfriend00 Apr 22 '19 at 21:20
  • There as been some discussion in the following post. The only alternative, which I don't necessarily recommend, relates to using 'rmdir' and checking for failure. https://stackoverflow.com/questions/14577960/node-js-how-to-check-if-folder-is-empty-or-not-with-out-uploading-list-of-files – user3570671 Apr 23 '19 at 23:09
  • @user3570671 - Do you think any of those are more efficient than just listing the files? FYI, the OS is dang good at giving you a list of files in a directory, even if there are thousands. Today's modern file systems are heavily optimized around efficient directory access. For example, the idea to use fs.rmdir followed by fs.mkdir requires multiple disk writes (not just reads if the directory is empty). And, all the other solutions that involve running shell commands mean firing up a new process. – jfriend00 Apr 23 '19 at 23:19
  • @user3570671 - So, if you want to go faster, you probably write your own OS-specific and OS-optimized node.js add-in to do this in C code and save the building of an array of Javascript filename strings or perhaps even use OS-level access to directory properties (that node.js does not expose). But, I'd be really surprised if that was worth the trouble. – jfriend00 Apr 23 '19 at 23:20
  • Unless the node implementation is returning some kind of iterable that is O(1) or at least something not iterating through all of the files, you will at some point run into a performance hit with enough files. The posted solution using readdir (whether you use it directly or indirectly), is indeed the solution I have used. I actually recommend listing all of the files over using rmdir because I foresee potential issues with permissions, etc., if the process is not the owner of the folder. I only point out the potential problem in hopes that someone has a more ideal solution. – user3570671 Apr 23 '19 at 23:27
25

simple sync function like you were trying for:

const fs = require('fs');

function isEmpty(path) {
    return fs.readdirSync(path).length === 0;
}
Russell Chisholm
  • 645
  • 9
  • 13
7

There is the possibility of using the opendir method call that creates an iterator for the directory.

This will remove the need to read all the files and avoid the potential memory & time overhead

import {promises as fsp} from "fs"
const dirIter = await fsp.opendir(_folderPath);
const {value,done} = await dirIter[Symbol.asyncIterator]().next();
await dirIter.close()

The done value would tell you if the directory is empty

johnmerm
  • 676
  • 8
  • 15