'check if file exists (case-sensitive)

Is there a way to check whether a file exists in NodeJS, with case-sensitivity, even when the underlying file system isn't case sensitive?

fs.exists() may or may not be case sensitive depending on the underlying file system.

 fs = require('fs');
 fs.existsSync('readme.txt') // true
 fs.existsSync('README.TXT') // false (or true, depending on the file system)

This causes problems when developing an app on a case-insensitive development environment that will be deployed on a case-sensitive server. I recently had an issue where the build was broken by a typo. It worked locally.

If I can get Node to tell me, "yes, README.TXT exists, and it's stored as readme.txt" that will be enough to solve the problem.



Solution 1:[1]

Since I can't comment < 50 rep I'll make a new post.

@patrik's solution was working nice except on windows because of the root check

I changed it to look like following:

function fileExistsWithCaseSync (filepath) {
  var dir = path.dirname(filepath)
  if (dir === path.dirname(dir)) {
    return true
  }
  var filenames = fs.readdirSync(dir)
  if (filenames.indexOf(path.basename(filepath)) === -1) {
    return false
  }
  return fileExistsWithCaseSync(dir)
}

Solution 2:[2]

Following Andrey's suggestion I implemented a function that uses readdir.

var fs = require('fs');
var path = require('path');

function fileExistsWithCaseSync(filepath) {
    var dir = path.dirname(filepath);
    if (dir === '/' || dir === '.') return true;
    var filenames = fs.readdirSync(dir);
    if (filenames.indexOf(path.basename(filepath)) === -1) {
        return false;
    }
    return fileExistsWithCaseSync(dir);
}

console.log(fileExistsWithCaseSync(__dirname + '/README.txt')) // false
console.log(fileExistsWithCaseSync(__dirname + '/readme.txt')) // true

I wouldn't use this function in production because each call makes several synchronous trips to the filesystem. But it's good enough for my needs: preventing my local development server from serving Foo.js when the file is actually called foo.js (which won't work in production).

Solution 3:[3]

Just to help someone who having this path problem.

The Patric's function pretty works for this case, but not solve the path issue. I found the true path module that actually solved my problem with case-sensitive paths on linux (ubuntu).

See more info here.

Solution 4:[4]

var fs = require('fs');
var path = require('path');

function fileExistsWithCaseSync(filepath) {
    var dir = path.dirname(filepath);
    if (filepath=== '/' || filepath=== '.') return true;
    var filenames = fs.readdirSync(dir);
    if (filenames.indexOf(path.basename(filepath)) === -1) {
        return false;
    }
    return fileExistsWithCaseSync(dir);
}

console.log(fileExistsWithCaseSync('./README.txt')) // false
console.log(fileExistsWithCaseSync('./readme.txt')) // true

check filepath use fileExistsWithCaseSync no __dirname

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Puck
Solution 2 Community
Solution 3 Luiz Fernando da Silva
Solution 4 W.Andy