Blargmode
Blargmode

Reputation: 1105

node.js fs.exists() will be deprecated, what to use instead?

According to the documentation node.js fs.exists() will be deprecated. Their reasoning:

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.

fs.exists() will be deprecated.

I am currently using it before moving files, since the fs.rename() seems to quietly overwrite files with the same name in the destination folder.

My question is; what should I use instead to prevent fs.rename() from overwriting the file in the destination folder? I assume there's a way that I don't know of. Otherwise I don't see a reason for fs.exists() to be deprecated.

Using fs.open() as suggested seems overkill since I don't want to open the file.


Edit, as per @jfriend00's request for more info about what I'm doing.

I'm making an Electron application where the user can sort files into different directories. It's not a server software, it's intended to run on every day users machines, handling their documents. This is the code so far for moving a file:

function moveFile(destIndex){
    var from = queue[currentQueueIndex].path;
    var to = destinations[destIndex].path + path.sep + path.basename(from);
    console.log("[i] Move file (from/to): ");
    console.log(from);
    console.log(to);

    //Check if file exists, if yes: give them the choice to cancel.
    fs.stat(to, function (err, stats) {
        if (err){
            move(from, to);
        } else {
            var confirmed = confirm("File already exists, will overwrite.");
            if (confirmed) {
                move(from, to);
            }
        }
    });
    next(); //Show the next file to the user
}

function move(from, to){
    fs.rename(from, to, function (err) {
        if (err) throw err;
        console.log('[i] Move successful');
        queue[currentQueueIndex].path = to;
        queue[currentQueueIndex].moved = true;
    });
}

After the first comment, the part starting with fs.stat, I check whether the file I'm about to create with fs.rename already exists. I guess this is subject to race conditions, but I can't find that fs.rename handles duplicates in any way.
Since this application is intended for "home computing", I don't think the scenario where a file disappears between the stat check and the rename is likely to happen. But still, the more potential problems I can avoid, the better.

Upvotes: 43

Views: 28779

Answers (5)

cdauth
cdauth

Reputation: 7597

Here is an example using fs.access (in older Node versions, use fs.stat instead of fs.access), but handling errors correctly as well:

import { access } from 'node:fs/promises';

async function fileExists(filename) {
    try {
        await access(filename);
        return true;
    } catch (err) {
        if (err.code === 'ENOENT') {
            return false;
        } else {
            throw err;
        }
    }
}

Upvotes: 13

Poyoman
Poyoman

Reputation: 1966

const exists = !!(await fs.promises.stat(filename).catch(() => null))

Upvotes: 4

DDN-Shep
DDN-Shep

Reputation: 443

Use fs.existsSync().

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: 23

vineet
vineet

Reputation: 14246

Here is example by using fs.stat:-

fs.stat('mycustomfile.csv', function (err, stats) {
   console.log(stats);//here we got all information of file in stats variable
   if (err) {
       return console.error(err);
   }
     fs.unlink('mycustomfile.csv',function(err){
        if(err) return console.log(err);
        console.log('file deleted successfully');
   });  
});

Upvotes: 4

mscdex
mscdex

Reputation: 106736

The io.js docs mention the use of fs.stat() or fs.access() in place of fs.exists().

Upvotes: 18

Related Questions