Node.js check if path is file or directory
Solution 1
The following should tell you. From the docs:
fs.lstatSync(path_string).isDirectory()
Objects returned from fs.stat() and fs.lstat() are of this type.
stats.isFile() stats.isDirectory() stats.isBlockDevice() stats.isCharacterDevice() stats.isSymbolicLink() // (only valid with fs.lstat()) stats.isFIFO() stats.isSocket()
NOTE:
The above solution will throw
an Error
if; for ex, the file
or directory
doesn't exist.
If you want a true
or false
approach, try fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();
as mentioned by Joseph in the comments below.
Solution 2
Update: Node.Js >= 10
We can use the new fs.promises API
const fs = require('fs').promises;
(async() => {
const stat = await fs.lstat('test.txt');
console.log(stat.isFile());
})().catch(console.error)
Any Node.Js version
Here's how you would detect if a path is a file or a directory asynchronously, which is the recommended approach in node. using fs.lstat
const fs = require("fs");
let path = "/path/to/something";
fs.lstat(path, (err, stats) => {
if(err)
return console.log(err); //Handle error
console.log(`Is file: ${stats.isFile()}`);
console.log(`Is directory: ${stats.isDirectory()}`);
console.log(`Is symbolic link: ${stats.isSymbolicLink()}`);
console.log(`Is FIFO: ${stats.isFIFO()}`);
console.log(`Is socket: ${stats.isSocket()}`);
console.log(`Is character device: ${stats.isCharacterDevice()}`);
console.log(`Is block device: ${stats.isBlockDevice()}`);
});
Note when using the synchronous API:
When using the synchronous form any exceptions are immediately thrown. You can use try/catch to handle exceptions or allow them to bubble up.
try{
fs.lstatSync("/some/path").isDirectory()
}catch(e){
// Handle error
if(e.code == 'ENOENT'){
//no such file or directory
//do something
}else {
//do something else
}
}
Solution 3
Seriously, question exists five years and no nice facade?
function isDir(path) {
try {
var stat = fs.lstatSync(path);
return stat.isDirectory();
} catch (e) {
// lstatSync throws an error if path doesn't exist
return false;
}
}
Solution 4
Depending on your needs, you can probably rely on node's path
module.
You may not be able to hit the filesystem (e.g. the file hasn't been created yet) and tbh you probably want to avoid hitting the filesystem unless you really need the extra validation. If you can make the assumption that what you are checking for follows .<extname>
format, just look at the name.
Obviously if you are looking for a file without an extname you will need to hit the filesystem to be sure. But keep it simple until you need more complicated.
const path = require('path');
function isFile(pathItem) {
return !!path.extname(pathItem);
}
Solution 5
If you need this when iterating over a directory1
Since Node 10.10+, fs.readdir
has withFileTypes
option which makes it return directory entry fs.Dirent
instead of just filename. Directory entry contains its name
and useful methods such as isDirectory
or isFile
, so you don't need to call fs.lstat
explicitly!
You can use it like this then:
import { promises as fs } from 'fs';
// ./my-dir has two subdirectories: dir-a, and dir-b
const dirEntries = await fs.readdir('./my-dir', { withFileTypes: true });
// let's filter all directories in ./my-dir
const onlyDirs = dirEntries.filter(de => de.isDirectory()).map(de => de.name);
// onlyDirs is now [ 'dir-a', 'dir-b' ]
1) Because that's how I've found this question.
ThomasReggi
Updated on July 08, 2022Comments
-
ThomasReggi almost 2 years
I can't seem to get any search results that explain how to do this.
All I want to do is be able to know if a given path is a file or a directory (folder).
-
AlexMA over 10 yearsNote that the asynchronous version is usually preferable if you care about general app performance.
-
Ethan Mick over 9 yearsKeep in mind that if the directory or file does not exist, then you will get an error back.
-
Jossef Harush Kadouri almost 6 years
let isDirExists = fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();
-
Sergey Kuznetsov over 5 yearsKeep in mind that if file or directory does not exists it will throw exception that needs to be caught otherwise it will cause abnormal exit.
-
electrovir about 5 yearsObviously this won't work in all situations but it's much quicker and easier than the other answers if you can make the needed assumptions.
-
alfreema over 4 yearsIs this still considered experimental as of Mar. 2020? Where can we look to see? -- Oops I see when I click the link above that it's now stable (which implies no longer experimental).
-
wow ow about 4 yearsthe directory could be named
folder.txt
and this would say its a file, or the file could beLICENSE
with no extensin -
wow ow about 4 yearswhat if the folder name has a dot at the end of it, like
.git
or evenmyFolder.txt
? -
TamusJRoyce about 4 yearsYou have to understand posix filepath conventions (which windows, in part, adheres to since Windows is posix complient in the kernel level). Please read stackoverflow.com/questions/980255/… and en.wikipedia.org/wiki/…
-
David Callanan almost 4 years@JossefHarush What happens if the file gets deleted between those steps?
-
David Callanan almost 4 yearsDoes
isDirectory
return true if it's a symlinked directory? -
Johncl over 3 yearsI find it odd that when they first made lstat they didnt just include an exists() function in there? I guess this is why node_modules is deeper than a black hole.
-
TamusJRoyce about 3 yearsDidn't really answer this did I? .git and myFolder.txt can be either a folder or a file. You don't know until you check. Since folders are also considered file, you cannot have a folder and a file named the same. .git/. and myFolder.txt/. are both folders. .git/ and myFolder.txt/ are all the files within that folder. man readline documents this (obscurely). The lone . is special. files/folders containing . are not.
-
TamusJRoyce about 3 years. and .. are both special
-
Marinos An about 3 years
[Error: EACCES: permission denied, scandir '/tmp/snap.skype']
when I provide/tmp/
which is a dir and accessible. -
snickle over 2 yearsWhy is everyone using
fs.lstat()
? The docs say it will always befalse
: "If the<fs.Stats>
object was obtained fromfs.lstat()
, this method [<fs.Stats>.isDirectory()
] will always returnfalse
. This is becausefs.lstat()
returns information about a symbolic link itself and not the path it resolves to." -
Clonkex over 2 years@MarinosAn I would assume you don't have read permission for that file, so it fails.
-
milahu over 2 years@snickle
fs.stat
will resolve all symlinks, and return stats for the real path. so it depends on the use case