The Deno TypeScript runtime has built-in functions, but none of them address checking the existence of a file or directory. How can one check if a file or directory exists?
There is the standard library implementation, here: https://deno.land/std/fs/mod.ts
import {existsSync} from "https://deno.land/std/fs/mod.ts";
const pathFound = existsSync(filePath)
console.log(pathFound)
This code will print true
if the path exists and false
if not.
And this is the async implementation:
import {exists} from "https://deno.land/std/fs/mod.ts"
exists(filePath).then((result : boolean) => console.log(result))
Make sure you run deno with the unstable flag and grant access to that file:
deno run --unstable --allow-read={filePath} index.ts
exists
and existsSync
have been removed in the latest std
library in favour of trying to read the file and handling the error if it doesn't exists. See @BentoumiTech answer below and this comment in the Deno repo which was adopted github.com/denoland/deno_std/issues/1216#issuecomment-937722077 –
Appeasement exists
has been undone with some changes. Please check my answer for details. –
Bioastronautics The Deno API changed since the release of Deno 1.0.0
. If the file is not found the exception raised is Deno.errors.NotFound
const exists = async (filename: string): Promise<boolean> => {
try {
await Deno.stat(filename);
// successful, file or directory must exist
return true;
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
// file or directory does not exist
return false;
} else {
// unexpected error, maybe permissions, pass it along
throw error;
}
}
};
exists("test.ts").then(result =>
console.log("does it exist?", result)); // true
exists("not-exist").then(result =>
console.log("does it exist?", result)); // false
As the original answer account is suspended and cannot change his answer if I comment on it, I'm reposting a fixed code snippet.
There is the standard library implementation, here: https://deno.land/std/fs/mod.ts
import {existsSync} from "https://deno.land/std/fs/mod.ts";
const pathFound = existsSync(filePath)
console.log(pathFound)
This code will print true
if the path exists and false
if not.
And this is the async implementation:
import {exists} from "https://deno.land/std/fs/mod.ts"
exists(filePath).then((result : boolean) => console.log(result))
Make sure you run deno with the unstable flag and grant access to that file:
deno run --unstable --allow-read={filePath} index.ts
exists
and existsSync
have been removed in the latest std
library in favour of trying to read the file and handling the error if it doesn't exists. See @BentoumiTech answer below and this comment in the Deno repo which was adopted github.com/denoland/deno_std/issues/1216#issuecomment-937722077 –
Appeasement exists
has been undone with some changes. Please check my answer for details. –
Bioastronautics There is no function that's specifically for checking if a file or directory exists, but the Deno.stat
function, which returns metadata about a path, can be used for this purpose by checking the potential errors against Deno.ErrorKind.NotFound
.
const exists = async (filename: string): Promise<boolean> => {
try {
await Deno.stat(filename);
// successful, file or directory must exist
return true;
} catch (error) {
if (error && error.kind === Deno.ErrorKind.NotFound) {
// file or directory does not exist
return false;
} else {
// unexpected error, maybe permissions, pass it along
throw error;
}
}
};
exists("test.ts").then(result =>
console.log("does it exist?", result)); // true
exists("not-exist").then(result =>
console.log("does it exist?", result)); // false
The deprecation of exists
has been undone in 0.182.0, since there are too many valid use cases, however you should avoid it as good as possible, because it potentially causes race conditions in your code, meaning your file or directory shall be tempered by a third party after checking for its existence, since exists
won't lock the file or directory.
For instance: If you want to remove a file only if it exists, instead of doing:
import { exists } from "https://deno.land/std/fs/mod.ts";
if (await exists("./foo")) {
await Deno.remove("./foo");
}
You should rather do:
try {
await Deno.remove("./foo");
} catch (error) {
if (!(error instanceof Deno.errors.NotFound)) {
throw error;
}
// Do nothing...
}
Same goes to editing files. If you are going to work with your file, just try to open/edit it and catch the exception.
However, there are valid use cases for exists
, such as checking if a file or directory exists for a third party tool and skipping to launch the tool if it's missing. This can be very handy, if the tool is expensive to launch or fails to report a proper error message on a wrong path.
But there were problems with the former exists
:
- Firstly, there was the pitfall in which you shall check for a directory and
exists
would returntrue
, but it was a file with the same name that was found at the destination, leading to follow-up errors. - Secondly,
exists
would returnfalse
if the file cannot be read only on Windows, but not on POSIX systems, because its underlyinglstat
call would still succeed on POSIX systems, despite the path being not readable by the user.
The new implementation solves all those issues and provides options that you certainly should make use of, if you really have to use exists
:
import { exists } from "https://deno.land/std/fs/mod.ts";
const fooDirExistsAndIsReadable = await exists("./foo", {
isReadable: true, // check if foo can be read on POSIX and Windows
isDirectory: true // check if foo is a directory
});
const barFileExistsAndIsReadable = await exists("./bar", {
isReadable: true, // check if bar can be read on POSIX and Windows
isFile: true // check if bar is a file
});
Other than that, you can still use the implementation like before:
const foobarExists = await exists("./foobar");
It is important to know that exists
uses stat
instead of lstat
now, meaning it now follows symlinks to make the options work as expected.
Disclaimer: I contributed the implementation to Deno after a fairly long discussion with a long back and forth and overthinking between all parties. I'm glad we made it, eventually.
The exists
function is actually part of the std/fs module although it is currently flagged as unstable. That means you need to deno run --unstable
: https://deno.land/std/fs/README.md#exists
© 2022 - 2024 — McMap. All rights reserved.
exists
has been undone. Please check my answer for important details. – Bioastronautics