This tutorial shows you how to get the list of files and directories inside a directory, including if there are nested sub directories.
If you want to get the list of entries inside a directory programmatically using Deno, there are already built-in functions that simplify the process. Below are the functions along with the usage examples and error handling.
Get List of Files and Directories
In Deno, you can easily get the list of files and directories using Deno.readDir
or Deno.readDirSync
. In order for the functions to work, you need to add --allow-read
flag in deno run
command since Deno needs read permission in order to read directories.
For this tutorial, let's assume there is a folder named data
in the current working directory. Below is the structure of the folder.
data
data1
file3.txt
file1.txt
file2.txt
Using Deno.readDir
Deno.readDir
is a function for reading a directory with the given path
.
function Deno.readDir(path: string | URL): AsyncIterable<DirEntry>
You need to pass the path to the directory, either relative or absolute. If you pass an absolute path, it must be relative to the current working directory which defaults to the location where you execute deno run
command. The working directory can be changed using Deno.chdir
command.
The function returns an async
iterable of DirEntry
. DirEntry
itself has the following fields.
string name
: The file name.boolean isFile
: Whether the entry is a file.boolean isDirectory
: Whether the entry is a directory.boolean isSymlink
: Whether the entry is a symlink.
To get the result, you need to iterate over the iterable. Below is the usage example.
for await (const dirEntry of Deno.readDir('data')) {
console.log(dirEntry);
}
{ name: "data1", isFile: false, isDirectory: true, isSymlink: false }
{ name: "file1.txt", isFile: true, isDirectory: false, isSymlink: false }
{ name: "file2.txt", isFile: true, isDirectory: false, isSymlink: false }
Get List of Files
The above example returns all entries including files and directories. To get the list of file names, you can filter entries whose value of isFile
field is true
.
const fileNames: string[] = [];
for await (const dirEntry of Deno.readDir('data')) {
if (dirEntry.isFile) {
fileNames.push(dirEntry.name);
}
}
console.log(fileNames);
Output:
[ "file1.txt", "file2.txt" ]
Get List of Directories
To get the list of directory names, you can filter entries whose value of isDirectory
field is true
.
const dirNames: string[] = [];
for await (const dirEntry of Deno.readDir('data')) {
if (dirEntry.isDirectory) {
dirNames.push(dirEntry.name);
}
}
console.log(dirNames);
Output:
[ "data1" ]
Get List in Nested Sub Directories
The Deno.readDir
command only lists the entries in the current directories, but not including the entries in sub directories. To get the list of files and directories in nested sub directories, you can do it recursively like the code below.
async function getNames(currentPath: string) {
const names: string[] = [];
for await (const dirEntry of Deno.readDir(currentPath)) {
const entryPath = `${currentPath}/${dirEntry.name}`;
names.push(entryPath);
if (dirEntry.isDirectory) {
names.push(await getNames(entryPath));
}
}
return names;
}
console.log(await getNames('data'));
Output:
[ "data/data1", "data/file1.txt", "data/file2.txt" ]
Using Deno.readDirSync
Deno.readDir
is similar to Deno.readDir
, but it performs the operation synchronously. It returns an iterable whose element type is also DirEntry
. If you want to filter files/directories only or get the list of entries in nested sub directories, you can use the above examples of readDir
as references.
function Deno.readDirSync(path: string | URL): Iterable<DirEntry>
Below is the usage example.
for (const dirEntry of Deno.readDirSync('data')) {
console.log(dirEntry);
}
Error Handling
There are things that may cause an error. For example if the passed path doesn't exist.
Check file:///home/ivan/Projects/deno/src/examples/dir_list.ts
error: Uncaught (in promise) NotFound: No such file or directory (os error 2)
at processResponse (core.js:223:11)
at Object.jsonOpAsync (core.js:240:12)
at async Object.[Symbol.asyncIterator] (deno:cli/rt/30_fs.js:125:16)
at async file:///home/ivan/Projects/deno/src/examples/dir_list.ts:1:18
Another cause of error is passing a path that's not a directory.
Check file:///home/ivan/Projects/deno/src/examples/dir_list.ts
error: Uncaught (in promise) Error: Not a directory (os error 20)
at processResponse (core.js:223:11)
at Object.jsonOpAsync (core.js:240:12)
at async Object.[Symbol.asyncIterator] (deno:cli/rt/30_fs.js:125:16)
at async file:///home/ivan/Projects/deno/src/examples/dir_list.ts:1:18
Or if the user that runs the application doesn't have sufficient permission to access a directory.
Check file:///home/ivan/Projects/deno/src/examples/dir_list.ts
error: Uncaught (in promise) PermissionDenied: Permission denied (os error 13)
at processResponse (core.js:223:11)
at Object.jsonOpAsync (core.js:240:12)
at async Object.[Symbol.asyncIterator] (deno:cli/rt/30_fs.js:125:16)
at async file:///home/ivan/Projects/deno/src/examples/dir_list.ts:1:18
You can wrap the code inside a try-catch block to handle any error that can be thrown while trying to read a directory.
try {
for await (const dirEntry of Deno.readDir('x')) {
console.log(dirEntry);
}
} catch (err) {
console.error(err);
}
Related Posts: