Node.js check if file exists - node.js

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')) {
// ...
}

Edit:
Since node v10.0.0we 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;
}

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.

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

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.");
}

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
}
});

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:
// http://stackoverflow.com/a/7550430/486547
//
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

A concise solution in async await style:
import { stat } from 'fs/promises';
const exists = await stat('foo.txt')
.then(() => true)
.catch(() => false);

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.

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?

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!

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.stator fsp.access for two reasons:
The least important reason - it is one less access.
It is possible that fsp.statand fsp.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
fs-extra
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:
path.resolve
fs.stat
fs.access
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
}

Related

When trying to write image file it moves ahead and write works late

What i am trying to do here is i am writing a image file after resizing it with node and after that i will use it to upload it. but when i am writing it my uploading code started at that time and file is still not written.
async function getdataFromJimpSmall(image,filePath,FILE_NAME){
try{
var isSucess = false ;
const im = await Jimp.read(image);
return new Promise((resolve, reject) => {
try{
im.resize(150, 215, Jimp.RESIZE_BEZIER, function(err){
if (err) throw err;
});
im.write(filePath+FILE_NAME)
resolve(true)
}
catch(err){
console.log(err);
reject(false);
}
})
}
catch(err){
console.log('getdataFromJimpSmall Err====>'+err)
return false
}
}
I tried to use this but it is getting ahead of my code
it started from here and it is getting called from here.
isThumbnailUrlavailable = await jimpController.imageCoverJimpAndUploadToS3small(getISBNBook, "-#gmail.com", "SaleIsbn")
isThumbnailUrlavailableMedium = await jimpController.imageCoverJimpAndUploadToS3medium(getISBNBook, "-#gmail.com", "SaleIsbn")
And the first function imageCoverJimpAndUploadToS3small() is this:
exports.imageCoverJimpAndUploadToS3small = async (getContent,email,file) =>{
try{
var elementType = 15;
var filePath = path.join(__dirname, '../../uploads/t/')
var FILE_NAME = `${getContent.contentMetaDataRef.isbn}_s.jpg`
var image = getContent.thumbnail
let tempdata = await getdataFromJimpSmall(image,filePath,FILE_NAME)
console.log('temp - ', tempdata);
if(tempdata==true)
{
var data = await commonController.uploadthumbnailTOPublicS3(filePath, FILE_NAME)
console.log('s3', data);
requestImageSize(data.url).then(size =>
{
console.log(size);
if(size.height>0&&size.width>0)
{
tempdata=true;
const getContentElement = ContentElement.findOne({contentId: getContent._id,elementType,elementData: data.keyName}).lean()
if(getContentElement){
ContentElement.findByIdAndUpdate(getContentElement._id, {
createdOn: Date(), modifiedOn: Date(),
}, { new: true })
}
else
{
return tempdata;
}else
{
tempdata=false;
return tempdata;
}
}).catch(err =>
{
console.error(err);
tempdata=false;
return tempdata;
});
}
}
catch(error){
console.log(error)
tempdata=false;
return tempdata;
}
}
But it is not working...
Again i am calling imageCoverJimpAndUploadToS3small() and it starts after that.
as per docs https://www.npmjs.com/package/jimp#writing-to-files-and-buffers, .write runs asynchronously and takes a callback, which is why the promise resolves before image is written
so, you need to use callback, and resolve from there:
im.write(filePath+FILE_NAME, (err)=>{
if(err) throw err;
resolve(true);
});
or, as the docs say, you might use and await .writeAsync, which is promise-based:
await im.writeAsync(filePath+FILE_NAME);
resolve(true);

How can you create multiple directories with paths received in response from from api call?

I am receiving a list of objects from the front-end and i want to create multiple directories from the values stored in that key value pairs. So far I tried this method but it isn't working.
filercv=layerorder.map(layer=>{
return `layers/${layer.name}`;
})
console.log(filercv)
var count
function makeAllDirs(root, list) {
return list.reduce((p, item) => {
return p.then(() => {
console.log(item)
console.log(root)
return mkdirp(path.join(root,item));
});
}, Promise.resolve());
}
// usage
makeAllDirs(basePath,filercv).then(() => {
console.log('yes')
}).catch(err => {
// error here
console.log(err)
});
};
//layerorder
layerorder=[{"name":"bodies"},{"name":"Top"}]
But when i run this code only one folder is created in the layers directory i.e bodies.
check within mkdirp(), maybe your path resolves to somewhere else, so check the final constructed path, or maybe the recursive flag is missing: fs.mkdir(path)
Also, try async/await, this will create folders in process.cwd():
const fs = require('fs');
const path = require('path');
function mkdirp(dir) {
return new Promise((resolve, reject) => {
console.log('--creating dir: ', path.resolve(dir));
fs.mkdir(dir, {
recursive: true
}, (err) => {
if (err) reject(err);
resolve();
});
});
}
//layerorder
const layerorder = [{
"name": "bodies"
}, {
"name": "Top"
}];
const filercv = layerorder.map(layer => {
return `layers/${layer.name}`;
});
console.log('dirs: ', filercv);
// check path
let basePath = process.cwd();
async function makeAllDirs() {
try {
await Promise.all(filercv.map(dir => {
console.log(`root: ${basePath}, item: ${dir}`);
return mkdirp(path.join(basePath, dir))
}));
console.log('yes');
} catch (err) {
console.log('no', err);
}
}
makeAllDirs();

Promise not working inside recursion function

i'm trying to create a function to check exist and not exist file names so i used recursion function and proimse but unfortunately it's not resolve anything when the condition is true i tried it like that
function checkFileName(n = 0) {
return new Promise((resolve, reject) => {
fs.open("./npm"+n+".txt", 'r', function(err, res) {
if (err) {
resolve("./npm"+n+".txt")
} else {
n++
checkFileName(n)
}
})
})
}
checkFileName().then(Name => {
console.log(Name)
})
but it's not resolve anything where's the wrong ?
Any specific reason you is doing it like that ?
// Node.js program to demonstrate the
// fs.readdir() method
// Import the filesystem module
const fs = require('fs');
const path = require('path');
// Function to get current filenames
// in directory with specific extension
fs.readdir(__dirname, (err, files) => {
if (err)
console.log(err);
else {
console.log("\Filenames with the .txt extension:");
files.forEach(file => {
if (path.extname(file) == ".txt")
console.log(file);
})
}
})
Instead of reading a file at the time, you can read the hole dir and iterate over them returned files
Please change checkFileName(n) to checkFileName(n).then(resolve)
One of the solutions would be as follows:
function checkFileName(n = 0) {
return new Promise((resolve) => {
const filePath = "./npm"+n+".txt";
fs.open(filePath, 'r', function(err, res) {
if (err) {
resolve(filePath)
} else {
checkFileName(n+1).then(resolve)
}
})
})
}
checkFileName().then(Name => {
console.log(Name)
})

Return a value from accessSync other than ENOENT

How would I return false from accessSync when it fails to find a file/dir instead of ENOENT?
unit test
it.only('should be able to read a file stream only if a file exist', function() {
let testfile = testpath+'/imageeee.png';
let ok = FileService.existsAsync(testfile);
ok = ok.then((result) => {
console.log('exists: ', result);
return FileService.createReadStream(testfile);
});
ok = ok.then((result) => {
assert.isNotNull(result.path);
assert.equal(result.path, testfile);
assert.isTrue(result.readable, true);
});
return ok;
});
function
existsAsync(path) {
let ok = fs.accessAsync(path, fs.F_OK);
ok = ok.then(function(error) {
if (error) {
return false;
} else {
return true;
}
});
return ok;
},
error
Error: ENOENT: no such file or directory, access '/home/j/Work/imageeee.png'
Anything that throws an error can be wrapped in a try...catch block to capture the error and proceed from there. If this is the problem function here:
fs.accessAsync(path, fs.F_OK);
Wrap it in a try catch and return false in the error case:
try {
fs.accessAsync(path, fs.F_OK);
// ... other code
return true;
} catch(e) {
// log the error ?
return false;
}
Consider this as an alternative solution to avoid the ENOENT error by using 'child_process' with cat instead of the 'fs' capabilities to know if a file exists or not (with an actual catch error exception working without interfere with your main current process).
const { exec } = require('child_process');
function is_file(path){
return new Promise(resolve => {
try {
exec(`cat ${path}`, (err, stdout, stderr) => { // cat required
if (err) {
resolve(false);
} else {
resolve(true);
}
});
} catch ( e ) { resolve(false); }
});
}
async function main(){
let file = `foo.txt`;
if ( (await is_file(file)) ) {
console.log(`file exists: ${file}`);
} else {
console.log(`no such file: ${file}`);
}
}
main();
the solution is to:
1) Promisify the method that calls accessAsync
2) resolve the error if there is one instead of rejecting it
This will still return the error if the result is false but it will not break the promise chain. In order to return false you can simply do resolve(false) but I found it more useful to actual return the error and handle it in my test.
modified code:
existsAsync(path) {
return new Promise((resolve, reject) => {
return fs.accessAsync(path, fs.F_OK, (err, data) => {
if (err) {
resolve(err);
} else {
resolve(true);
}
});
});
},

Mocking specific reading file error for tests in Node.js

Is it possible to mock, let's say, with the "mock-fs" library some sort of reading file errors? In particular, I want to test this case (where code !== 'ENOENT'):
fs.readFile(filePath, (err, data) => {
if (err) {
if (err.code !== 'ENOENT') {
return done(new ReadingFileError(filePath));
}
}
// ...
});
I could find nothing about emulating reading errors in their docs. Maybe there are some other libraries that can do this.
As far as I know mock-fs mocks the filesystem not the node utility. Of course in some case you can use that to test the fs utility, but I think your use case is not amongs them.
Here is an example with sinon.sandbox
Some alternatives are:
proxyquire (see example below)
testdouble
Note, that I am a bit confused where the ReadingFileError comes from, so I guess you are trying to implement a custom error. If that is the case maybe this also will be helpful. In the example I replaced that with a simple new Error('My !ENOENT error').
// readfile.js
'use strict'
const fs = require('fs')
function myReadUtil (filePath, done) {
fs.readFile(filePath, (err, data) => {
if (err) {
if (err.code !== 'ENOENT') {
return done(err, null)
}
return done(new Error('My ENOENT error'), null)
}
return done(null, data)
})
}
module.exports = myReadUtil
// test.js
'use strict'
const assert = require('assert')
const proxyquire = require('proxyquire')
const fsMock = {
readFile: function (path, cb) {
cb(new Error('My !ENOENT error'), null)
}
}
const myReadUtil = proxyquire('./readfile', { 'fs': fsMock })
myReadUtil('/file-throws', (err, file) => {
assert.equal(err.message, 'My !ENOENT error')
assert.equal(file, null)
})
Edit: Refactored the example to use node style callback instead of throw and try/catch

Resources