Rahul Iyer
Rahul Iyer

Reputation: 21025

How to check if a file or directory exists without using fs.exists?

The reason I ask, is because Node.js on ubuntu doesn't seem to have the fs.exists() function. Although I can call this when I run Node.js on my Mac, when I deploy to the server, it fails with an error saying the function does not exist.

Now, I am aware that some people consider it an "anti-pattern" to check if a file exists and then try and edit / open it etc, but in my case, I never delete these files, but I still need to check if they exist before writing to them.

So how can I check if the directory (or file) exists ?

EDIT:

This is the code I run in a file called 'temp.'s' :

var fs=require('fs');
fs.exists('./temp.js',function(exists){
    if(exists){
        console.log('yes');
    }else{
        console.log("no");
    }
});

On my Mac, it works fine. On ubuntu I get the error:

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^ TypeError: Object #<Object> has no method 'exists'
    at Object.<anonymous> (/home/banana/temp.js:2:4)
    at Module._compile (module.js:441:26)
    at Object..js (module.js:459:10)
    at Module.load (module.js:348:32)
    at Function._load (module.js:308:12)
    at Array.0 (module.js:479:10)
    at EventEmitter._tickCallback (node.js:192:41)

On my Mac - version : v0.13.0-pre On Ubuntu - version : v0.6.12

Upvotes: 5

Views: 18889

Answers (3)

F&#225;bio Zangirolami
F&#225;bio Zangirolami

Reputation: 1956

The Sync methods don't have any way of notifying about an error. Except for exceptions! As it turns out, the fs.statSync method throws an exception when the file or directory doesn't exist. Creating the sync version is as easy as that:

  function checkDirectorySync(directory) {
  try {
    fs.statSync(directory);
  } catch(e) {    
    try {
        fs.mkdirSync(directory);
    } catch(e) {
        return e;
    }
  }
}

And that's it. Using is as simple as before:

checkDirectorySync("./logs");  
//directory created / exists, all good.

[]´z

Upvotes: 1

manbearshark
manbearshark

Reputation: 141

The accepted answer does not take into account that the node fs module documentation recommends using fs.stat to replace fs.exists (see the documentation).

I ended up going with this:

function filePathExists(filePath) {
  return new Promise((resolve, reject) => {
    fs.stat(filePath, (err, stats) => {
      if (err && err.code === 'ENOENT') {
        return resolve(false);
      } else if (err) {
        return reject(err);
      }
      if (stats.isFile() || stats.isDirectory()) {
        return resolve(true);
      }
    });
  });
}

Note ES6 syntax + Promises - the sync version of this would be a bit simpler. Also my code also checks to see if there is a directory present in the path string and returns true if stat is happy with it - this may not be what everyone wants.

Upvotes: 6

Scimonster
Scimonster

Reputation: 33409

It's probably due to the fact that in NodeJs 0.6 the exists() method was located in the path module: http://web.archive.org/web/20111230180637/http://nodejs.org/api/path.htmltry-catch-finally

^^ That comment answers why it isn't there. I'll answer what you can do about it (besides not using ancient versions).

From the fs.exists() documentation:

In particular, checking if a file exists before opening it is an anti-pattern that leaves you vulnerable to race conditions: another process may remove the file between the calls to fs.exists() and fs.open(). Just open the file and handle the error when it's not there.

You could do something like this:

fs.open('mypath','r',function(err,fd){
    if (err && err.code=='ENOENT') { /* file doesn't exist */ }
});

Upvotes: 7

Related Questions