Calvin Froedge
Calvin Froedge

Reputation: 16373

fs.exists, fs.existsSync - why are they deprecated?

I noticed that the official node documentation says something startling about fs.exists:

"fs.exists() is an anachronism and exists only for historical reasons. There should almost never be a reason to use it in your own code.

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."

I understand the suggestion, to open a file and then handle the error if it doesn't exist, but what I don't understand is why the interface is being deprecated rather than the implementation simply changing.

Can anyone explain to me why checking for the existence of a file with an API that is as simple and logical as fs.exists is such a bad thing that it should be called an anti-pattern and removed from the node API?

Upvotes: 27

Views: 19364

Answers (7)

SetupX
SetupX

Reputation: 413

existsSync's implementation is like this (v0.10.25):

function (path) {
  try {
    nullCheck(path);
    binding.stat(pathModule._makeLong(path));
    return true;
  } catch (e) {
    return false;
  }
}

so if you write program like if(fs.existsSync(thepath)){}, it is better to change it to if(fs.statSync(thepath)){}.

Upvotes: 1

vaibhav hake
vaibhav hake

Reputation: 19

You can use new install for this one and continue to use it:
https://github.com/imyller/node-fs-exists-nodeback

npm install fs-exists-nodeback

Upvotes: 0

DDN-Shep
DDN-Shep

Reputation: 443

There is no need to use fs.stat(), because fs.existsSync() has not been deprecated.

https://nodejs.org/api/fs.html#fs_fs_existssync_path

fs.existsSync(path)

Added in: v0.1.21 path | Synchronous version of fs.exists(). Returns true if the file exists, false otherwise.

Note that fs.exists() is deprecated, but fs.existsSync() is not. (The callback >parameter to fs.exists() accepts parameters that are inconsistent with other >Node.js callbacks. fs.existsSync() does not use a callback.)

Upvotes: 9

risto
risto

Reputation: 1304

I think it because it's redundant. You can check if a file exists by trying to open it. It will give you ENOENT if it doesn't exist:

> fs.open('foo', 'r', function(err, fd) {
    ... console.log(err, fd);
    ... 
})
undefined
> { [Error: ENOENT, open 'foo'] errno: 34, code: 'ENOENT', path: 'foo' } undefined

Upvotes: 7

Michael
Michael

Reputation: 1864

Being deprecated because it's an anti-pattern according to some. I.e. it's not safe to trust exists() and then doing something with the file because the file can be removed in between the exists-call and the doing-something-call.

I agree in the above case. But to me, there is more use of exists(). I place empty dummy files in my temp- and cache directories. When I perform dangerous operations, such as removing old files from the cache dir I look for my dummy file to ensure that I'm not operating in the wrong directory. I.e. I just need to confirm that the file is there. Exists suits the bill perfectly for this, but I guess I'll switch to using stat() instead.

Upvotes: 7

iuppiter
iuppiter

Reputation: 321

I was searching for a solution to this issue and found that fs.exists and fs.existsSync was deprecated. This seems to work well in my senario

fs.readFile(filename, 'utf8', function(err,data){
    // the err variable substitutes for the fs.exists callback function variable
    if (!err){
        // do what you planned with the file
        console.log(data)
    }else{
        // handle the non-existence of the file
        console.log('File does not exist!');
    }
});

Upvotes: -2

SLaks
SLaks

Reputation: 887857

Because of the second paragraph you quoted.

There is no point in checking whether a file exists, because it could always be deleted right after the check.

Upvotes: 7

Related Questions