|
5 | 5 | * @run --allow-read --allow-write <url>
|
6 | 6 | * @group File System
|
7 | 7 | *
|
8 |
| - * Sometimes we as developers think that we need to check |
9 |
| - * if a file exists or not. More often than not, we are |
10 |
| - * entirely wrong. |
| 8 | + * When creating files it can be useful to first ensure that |
| 9 | + * such a file doesn't already exist. |
| 10 | + * There are a number of ways to do this. |
11 | 11 | */
|
12 | 12 |
|
13 |
| -// Let's say we wanted to create a folder if one doesn't |
14 |
| -// already exist. Logically it makes sense to first verify |
15 |
| -// that the folder exists, then try to create it right? |
16 |
| -// Wrong. This will create a race condition where if a folder |
17 |
| -// gets created in between when you check if the folder exists |
18 |
| -// and when you create a folder, your program will crash. |
19 |
| -// Instead, you should just create a folder and try to catch |
20 |
| -// errors like so. |
21 |
| -try { |
22 |
| - await Deno.mkdir("new_dir"); |
23 |
| -} catch (err) { |
24 |
| - if (!(err instanceof Deno.errors.AlreadyExists)) { |
25 |
| - throw err; |
26 |
| - } |
27 |
| -} |
| 13 | +// Use the `exists` utility from the std library to check for existence of a file or folder. |
| 14 | +// Note: Can create a race condition if followed by file operation. |
| 15 | +// Consider the alternative below. |
| 16 | +import { exists } from "jsr:@std/fs/exists"; |
| 17 | +await exists("./this_file_or_folder_exists"); // true |
| 18 | +await exists("./this_file_or_folder_does_not_exist"); // false |
| 19 | + |
| 20 | +// We can also use this function to check if the item on a path is a file or a directory |
| 21 | +await exists("./file", { isFile: true }); // true |
| 22 | +await exists("./directory", { isFile: true }); // false |
28 | 23 |
|
29 |
| -// This applies to almost every usecase. If you have a niche |
30 |
| -// usecase that requires you to check for existence of a file |
31 |
| -// without doing an filesystem operations other than that |
32 |
| -// (which is quite rare), then you can simply lstat the file |
33 |
| -// and catch the error. |
| 24 | +// Do not use the above function if performing a check directly before another operation on that file. |
| 25 | +// Doing so creates a race condition. The `exists` function is not recommended for that usecase. |
| 26 | +// Consider this alternative which checks for existence of a file without doing any other filesystem operations. |
34 | 27 | try {
|
35 |
| - await Deno.lstat("example.txt"); |
36 |
| - console.log("exists!"); |
| 28 | + const stats = await Deno.lstat("example.txt"); |
37 | 29 | } catch (err) {
|
38 | 30 | if (!(err instanceof Deno.errors.NotFound)) {
|
39 | 31 | throw err;
|
40 | 32 | }
|
41 |
| - console.log("not exists!"); |
| 33 | + console.log("File does not exist"); |
42 | 34 | }
|
0 commit comments