How do I check for the existence of a file?
Consider opening or reading the file directly, to avoid race conditions:
const fs = require('fs');
fs.open('foo.txt', 'r', (err, fd) => {
// ...
});
fs.readFile('foo.txt', (err, data) => {
if (!err && data) {
// ...
}
})
Using fs.existsSync
:
if (fs.existsSync('foo.txt')) {
// ...
}
Using fs.stat
:
fs.stat('foo.txt', function(err, stat) {
if (err == null) {
console.log('File exists');
} else if (err.code === 'ENOENT') {
// file does not exist
fs.writeFile('log.txt', 'Some log\n');
} else {
console.log('Some other error: ', err.code);
}
});
Deprecated:
fs.exists
is deprecated.
Using path.exists
:
const path = require('path');
path.exists('foo.txt', function(exists) {
if (exists) {
// ...
}
});
Using path.existsSync
:
if (path.existsSync('foo.txt')) {
// ...
}
fs.exists
works too. I have had problems with permissions to the file. –
Grati path.exists
actually is deprecated in favor of fs.exists
–
Hecklau fs.exists
and fs.existsSync
have also been deprecated. The best way to check file existence is fs.stat
, as demoed above. –
Entozoon fs.existsSync
is no longer depricated, though fs.exists
still is. –
Newkirk nodejs fs documentation
only says fs.exists
is deprecated, but that fs.existsSync
is fine ??? –
Consecration exists()
kind of API answers the question directly and can be used directly in a condition. –
Dancette Edit:
Since node v10.0.0
we could use fs.promises.access(...)
Example async code that checks if file exists:
function checkFileExists(file) {
return fs.promises.access(file, fs.constants.F_OK)
.then(() => true)
.catch(() => false)
}
An alternative for stat might be using the new fs.access(...)
:
minified short promise function for checking:
s => new Promise(r=>fs.access(s, fs.constants.F_OK, e => r(!e)))
Sample usage:
let checkFileExists = s => new Promise(r=>fs.access(s, fs.constants.F_OK, e => r(!e)))
checkFileExists("Some File Location")
.then(bool => console.log(´file exists: ${bool}´))
expanded Promise way:
// returns a promise which resolves true if file exists:
function checkFileExists(filepath){
return new Promise((resolve, reject) => {
fs.access(filepath, fs.constants.F_OK, error => {
resolve(!error);
});
});
}
or if you wanna do it synchronously:
function checkFileExistsSync(filepath){
let flag = true;
try{
fs.accessSync(filepath, fs.constants.F_OK);
}catch(e){
flag = false;
}
return flag;
}
fs.constants.F_OK
etc. Is it also possible to access them like fs.F_OK
? Weird. Also terse, which is nice. –
Feliciafeliciano fs.promises.access(path, fs.constants.F_OK);
to simply make it a Promise instead of creating a Promise. –
Tradelast !(await fs.stat(path).catch(() => false))
exists: !!(await fs.stat(path).catch(() => false))
–
Formulism fs.exists
one...really wonder why they force us to use such alternatives :'-( –
Cardin fs.constants.F_OK
, the flag indicating that the file is visible to the calling process, is not needed. It is the default. Just try
–catch
await fs.access(path)
. –
Conversation A easier way to do this synchronously.
if (fs.existsSync('/etc/file')) {
console.log('Found file');
}
The API doc says how existsSync
work:
Test whether or not the given path exists by checking with the file system.
fs.existsSync
was deprecated, but it no longer is. –
Newkirk Modern async/await way ( Node 12.8.x )
const fileExists = async path => !!(await fs.promises.stat(path).catch(e => false));
const main = async () => {
console.log(await fileExists('/path/myfile.txt'));
}
main();
We need to use fs.stat() or fs.access()
because fs.exists(path, callback)
now is deprecated
Another good way is fs-extra
const fileExists = path => fs.promises.stat(path).then(() => true, () => false);
–
Cymose fs
with const fs = require("node:fs/promises"):
then you can remove .promises
from the code too. –
Cymose fs.exists(path, callback)
and fs.existsSync(path)
are deprecated now, see https://nodejs.org/api/fs.html#fs_fs_exists_path_callback and https://nodejs.org/api/fs.html#fs_fs_existssync_path.
To test the existence of a file synchronously one can use ie. fs.statSync(path)
. An fs.Stats
object will be returned if the file exists, see https://nodejs.org/api/fs.html#fs_class_fs_stats, otherwise an error is thrown which will be catched by the try / catch statement.
var fs = require('fs'),
path = '/path/to/my/file',
stats;
try {
stats = fs.statSync(path);
console.log("File exists.");
}
catch (e) {
console.log("File does not exist.");
}
fs
variable comes from –
Plumbaginaceous fs.existsSync()
is no longer deprecated. –
Newkirk existsSync
" is deprecated exactly? –
Bless A concise solution in async await style:
import { stat } from 'fs/promises';
const exists = await stat('foo.txt')
.then(() => true)
.catch(() => false);
await
, then do try
/catch
too... –
Mf Aug 2021
After reading all posts:
let filePath = "./directory1/file1.txt";
if (fs.existsSync(filePath)) {
console.log("The file exists");
} else {
console.log("The file does not exist");
}
Old Version before V6: here's the documentation
const fs = require('fs');
fs.exists('/etc/passwd', (exists) => {
console.log(exists ? 'it\'s there' : 'no passwd!');
});
// or Sync
if (fs.existsSync('/etc/passwd')) {
console.log('it\'s there');
}
UPDATE
New versions from V6: documentation for fs.stat
fs.stat('/etc/passwd', function(err, stat) {
if(err == null) {
//Exist
} else if(err.code == 'ENOENT') {
// NO exist
}
});
fs.exists
and fs.existsSync
are deprecated according to the link you shared. –
Mirandamire existsSync
is not deprecated as per that doc, may be it was when you read it. –
Urias There are a lot of inaccurate comments about fs.existsSync()
being deprecated; it is not.
https://nodejs.org/api/fs.html#fs_fs_existssync_path
Note that fs.exists() is deprecated, but fs.existsSync() is not.
@Fox: great answer! Here's a bit of an extension with some more options. It's what I've been using lately as a go-to solution:
var fs = require('fs');
fs.lstat( targetPath, function (err, inodeStatus) {
if (err) {
// file does not exist-
if (err.code === 'ENOENT' ) {
console.log('No file or directory at',targetPath);
return;
}
// miscellaneous error (e.g. permissions)
console.error(err);
return;
}
// Check if this is a file or directory
var isDirectory = inodeStatus.isDirectory();
// Get file size
//
// NOTE: this won't work recursively for directories-- see:
// https://mcmap.net/q/93548/-how-to-get-totalsize-of-files-in-directory
//
var sizeInBytes = inodeStatus.size;
console.log(
(isDirectory ? 'Folder' : 'File'),
'at',targetPath,
'is',sizeInBytes,'bytes.'
);
}
P.S. check out fs-extra if you aren't already using it-- it's pretty sweet. https://github.com/jprichardson/node-fs-extra)
fs.exists
has been deprecated since 1.0.0. You can use fs.stat
instead of that.
var fs = require('fs');
fs.stat(path, (err, stats) => {
if ( !stats.isFile(filename) ) { // do this
}
else { // do this
}});
Here is the link for the documentation fs.stats
stats.isFile()
does not need filename
. –
Kamilahkamillah For those who ❤️ async-await
import fsp from 'fs/promises';
async function doesFileExist(path) {
try {
return (await fsp.stat(path)).isFile();
} catch (e) {
return false;
}
}
const path = './dir/file.pdf';
console.log(await doesFileExist(path));
Simple one-liner with Node.js fs/promises
import fs from 'node:fs/promises';
let exists = await fs.access('file.txt').then(() => true).catch(() => false);
exists
will be true
if the file exists, or false
if it doesn't.
See also:
async/await
version using util.promisify
as of Node 8:
const fs = require('fs');
const { promisify } = require('util');
const stat = promisify(fs.stat);
describe('async stat', () => {
it('should not throw if file does exist', async () => {
try {
const stats = await stat(path.join('path', 'to', 'existingfile.txt'));
assert.notEqual(stats, null);
} catch (err) {
// shouldn't happen
}
});
});
describe('async stat', () => {
it('should throw if file does not exist', async () => {
try {
const stats = await stat(path.join('path', 'to', 'not', 'existingfile.txt'));
} catch (err) {
assert.notEqual(err, null);
}
});
});
fs.statSync(path, function(err, stat){
if(err == null) {
console.log('File exists');
//code when all ok
}else if (err.code == "ENOENT") {
//file doesn't exist
console.log('not file');
}
else {
console.log('Some other error: ', err.code);
}
});
After a bit of experimentation, I found the following example using fs.stat
to be a good way to asynchronously check whether a file exists. It also checks that your "file" is "really-is-a-file" (and not a directory).
This method uses Promises, assuming that you are working with an asynchronous codebase:
const fileExists = path => {
return new Promise((resolve, reject) => {
try {
fs.stat(path, (error, file) => {
if (!error && file.isFile()) {
return resolve(true);
}
if (error && error.code === 'ENOENT') {
return resolve(false);
}
});
} catch (err) {
reject(err);
}
});
};
If the file does not exist, the promise still resolves, albeit false
. If the file does exist, and it is a directory, then is resolves true
. Any errors attempting to read the file will reject
the promise the error itself.
For asynchronous version! And with the promise version! Here the clean simple way!
try {
await fsPromise.stat(filePath);
/**
* File exists!
*/
// do something
} catch (err) {
if (err.code = 'ENOENT') {
/**
* File not found
*/
} else {
// Another error!
}
}
A more practical snippet from my code to illustrate better:
try {
const filePath = path.join(FILES_DIR, fileName);
await fsPromise.stat(filePath);
/**
* File exists!
*/
const readStream = fs.createReadStream(
filePath,
{
autoClose: true,
start: 0
}
);
return {
success: true,
readStream
};
} catch (err) {
/**
* Mapped file doesn't exists
*/
if (err.code = 'ENOENT') {
return {
err: {
msg: 'Mapped file doesn\'t exists',
code: EErrorCode.MappedFileNotFound
}
};
} else {
return {
err: {
msg: 'Mapped file failed to load! File system error',
code: EErrorCode.MappedFileFileSystemError
}
};
}
}
The example above is just for demonstration! I could have used the error event of the read stream! To catch any errors! And skip the two calls!
Well I did it this way, as seen on https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback
fs.access('./settings', fs.constants.F_OK | fs.constants.R_OK | fs.constants.W_OK, function(err){
console.log(err ? 'no access or dir doesnt exist' : 'R/W ok');
if(err && err.code === 'ENOENT'){
fs.mkdir('settings');
}
});
Is there any problem with this?
Using typescript and fs/promises in node14
import * as fsp from 'fs/promises';
try{
const = await fsp.readFile(fullFileName)
...
} catch(e) { ...}
It is better to use fsp.readFile
than fsp.stat
or fsp.access
for two reasons:
- The least important reason - it is one less access.
- It is possible that
fsp.stat
andfsp.readFile
would give different answers. Either due to subtle differences in the questions they ask, or because the files status changed between the calls. So the coder would have to code for two conditional branches instead of one, and the user might see more behaviors.
in old days before sit down I always check if chair is there then I sit else I have an alternative plan like sit on a coach. Now node.js site suggest just go (no needs to check) and the answer looks like this:
fs.readFile( '/foo.txt', function( err, data )
{
if(err)
{
if( err.code === 'ENOENT' )
{
console.log( 'File Doesn\'t Exist' );
return;
}
if( err.code === 'EACCES' )
{
console.log( 'No Permission' );
return;
}
console.log( 'Unknown Error' );
return;
}
console.log( data );
} );
code taken from http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/ from March 2014, and slightly modified to fit computer. It checks for permission as well - remove permission for to test chmod a-r foo.txt
vannilla Nodejs callback
function fileExists(path, cb){
return fs.access(path, fs.constants.F_OK,(er, result)=> cb(!err && result)) //F_OK checks if file is visible, is default does no need to be specified.
}
the docs say you should use access()
as a replacement for deprecated exists()
Nodejs with build in promise (node 7+)
function fileExists(path, cb){
return new Promise((accept,deny) =>
fs.access(path, fs.constants.F_OK,(er, result)=> cb(!err && result))
);
}
Popular javascript framework
var fs = require('fs-extra')
await fs.pathExists(filepath)
As you see much simpler. And the advantage over promisify is that you have complete typings with this package (complete intellisense/typescript)! Most of the cases you will have already included this library because (+-10.000) other libraries depend on it.
You can use fs.stat
to check if target is a file or directory and you can use fs.access
to check if you can write/read/execute the file. (remember to use path.resolve
to get full path for the target)
Documentation:
Full example (TypeScript)
import * as fs from 'fs';
import * as path from 'path';
const targetPath = path.resolve(process.argv[2]);
function statExists(checkPath): Promise<fs.Stats> {
return new Promise((resolve) => {
fs.stat(checkPath, (err, result) => {
if (err) {
return resolve(undefined);
}
return resolve(result);
});
});
}
function checkAccess(checkPath: string, mode: number = fs.constants.F_OK): Promise<boolean> {
return new Promise((resolve) => {
fs.access(checkPath, mode, (err) => {
resolve(!err);
});
});
}
(async function () {
const result = await statExists(targetPath);
const accessResult = await checkAccess(targetPath, fs.constants.F_OK);
const readResult = await checkAccess(targetPath, fs.constants.R_OK);
const writeResult = await checkAccess(targetPath, fs.constants.W_OK);
const executeResult = await checkAccess(targetPath, fs.constants.X_OK);
const allAccessResult = await checkAccess(targetPath, fs.constants.F_OK | fs.constants.R_OK | fs.constants.W_OK | fs.constants.X_OK);
if (result) {
console.group('stat');
console.log('isFile: ', result.isFile());
console.log('isDir: ', result.isDirectory());
console.groupEnd();
}
else {
console.log('file/dir does not exist');
}
console.group('access');
console.log('access:', accessResult);
console.log('read access:', readResult);
console.log('write access:', writeResult);
console.log('execute access:', executeResult);
console.log('all (combined) access:', allAccessResult);
console.groupEnd();
process.exit(0);
}());
Using Promise
import { existsSync } from 'fs'
const exists = (filepath) => new Promise((res) => {
existsSync(filepath) ? res(true) : res(false)
})
// Usage #1 (async/await)
const doesItExist = await exists('foo.txt')
if (doesItExist == false) {
// create the file
}
// Usage #2 (thenable)
exists('foo.txt').then(doesItExist => {
if (!doesItExist) {
// create file
}
})
But honestly it's rare to have a case like that,
Usually you'll just go with
import { existsSync as exists } from 'fs'
if (exists('foo.txt')) {
// do something
}
import { promisify } from 'util'
instead of using the *sync methods for all file system operations. In this particular example, the promise doesn't do anything for you because the operation in the promise is synchronous. –
Rachellrachelle const doesItExist = await exists('foo.txt') if (doesItExist == false) {
could be simply if (!(await exists('foo.txt'))) {
. "But honestly it's rare to have a case like that" -- is running an Express server a rare case? Seems like resorting to blocking Sync functions is the exceptional case, not the other way around. –
Cymose exists('foo.txt').then(...); ...
(in other words executing code without waiting for exists
function to give an answer. ¯_(ツ)_/¯ –
Hl .then()
is just misleading the caller. You can slap a promise onto a function that runs a for
loop that counts to a million and the code will still tie up the Node thread until it's done, just like existsSync
will. –
Cymose fs/promises
, my answer is outdated anyway, but I wouldn't mind using this solution for something else if that helps hybrid code. –
Hl existsSync
without the silly, misleading promise wrapper. Two good options: efficient promise-based code (best) or slow, synchronous code (acceptable in some cases). This proposal: slow and promise-based for no good reason (unacceptable in any situation). –
Cymose © 2022 - 2024 — McMap. All rights reserved.
fs.access('file', err => err ? 'does not exist' : 'exists')
, see fs.access – Nonchalantfs.access()
(elsewhere recommended on this page) to check file access without the follow-up intention to also read/manipulate the file. – Hematuria