Wisdom Ekpot A student of Ibom Metropolitan Polytechnic studying computer engineering, Wisdom has been writing JavaScript for two years, focusing on Vue.js, Angular, and Express.js.

Understanding Deno’s file system

4 min read 1205

Understanding Deno’s File System

Deno comes with its own file system as a core module. This file system module can be used for any kind of file or directory manipulation.

In this tutorial, we’ll go through the file system methods you can use in your Deno application.

Presently, some methods are still experimental and quite unstable; you should always add the --unstable flag when using these methods.

We’ll walk you through the following:

How to write files in Deno

There are several ways to write a file in Deno. They all require the --allow-write flag and will throw an error if one occurs.

You can use Deno.writeTextFile or Deno.writeFile to write text into a file. Deno.writeTextFile comes in both synchronous and asynchronous format and takes in two parameters: the location of the file and the content to be written into the file below.

// using the async method
await Deno.writeTextFile('./file.txt', 'This is the content to be written');

//using sync method
Deno.writeTextFileSync('./file.txt', 'This is the content to be written');

You can also use the Deno.writeFile method with a TextEncoder. The TextEncoder converts strings to Uint8Array:

const encoder = new TextEncoder(); // to convert a string to Uint8Array
await Deno.writeFile("./file.txt", encoder.encode("Content to be written"));

Finally, you can use the Deno.open and Deno.writeAll methods to open a file, write content to it, and then close the file, as shown below.

const file = await Deno.open("./image.png", { write: true, create: true }); //this opens the file
await Deno.writeAll(file, imageBytes); //writes to file
file.close(); // closes the file

If you try to write to a file that does not exist, Deno automatically creates the file.

How to read files in Deno

Like writing files, there are myriad ways to read files in Deno, all of which require the --allow-read flag.

We made a custom demo for .
No really. Click here to check it out.

You can use the Deno.readTextFile and Deno.readFile methods to read a file in Deno. Deno.readTextFile comes in both synchronous and asynchronous format and takes in the file path as a parameter:

// using the async method
const text = await Deno.readTextFile("file.txt");
console.log(text);

//using the sync method
const sync = Deno.readTextFileSync("file.txt");
console.log(sync);

Another method is Deno.readFile. You must first decode the file to a readable format using the TextDecoder method.

const decoder = new TextDecoder("utf-8");
const text = decoder.decode(await Deno.readFile("file.txt"));

console.log(text);

Remove files in Deno (remove and removeSync)

To remove files in Deno, use either the remove or removeSync method.

// Deno remove file asynchronous (non-block)
await Deno.remove("file.txt");

// Deno remove file synchronous (blocking way)
Deno.removeSync("image.png");

If you try to delete a file that doesn’t exist, Deno throws an error.

Uncaught NotFound: No such file or directory (os error 2)

Check for a folder in your directory (ensureDir)

The ensureDir method ensures that a folder exists in your working directory. You can use it to write a simple program.

Let’s write a simple program that checks if a folder exist. If the folder exists, it creates a new file and adds some text content to it.

To use this method, you must import it into your application. Create a notes folder inside your working directory. This is where you’ll store your note.

import { ensureDir, ensureDirSync } from "https://deno.land/std/fs/mod.ts";

Like the other methods we’ve discussed so far, this one comes in both asynchronous and synchronous format. Here’s how to use the asynchronous method:

ensureDir("./notes")
  .then(() => Deno.writeTextFile("./notes/note1.txt", "This is the content for note 1")); 

Copy file contents (copy)

The copy method enables you to duplicate file contents to another file.

To import the copy method into your Deno application:

import { copy } from "https://deno.land/std/fs/mod.ts";
copy("file.txt", "test.txt", {
  overwrite: true,
});

This method copies the file contents from file.txt to test.txt. It also takes some options. The overwrite option, for example, overwrites the content of the file to which you are copying the content.

Check for a directory (exists)

The exists method checks if a directory exists. exists returns a promise while existsSync returns a boolean.

Let’s write a simple program that will check if a directory exists or not:

import { exists, existsSync } from "https://deno.land/std/fs/mod.ts";

exists("./notes").then((res) => console.log(res)); //res here returns a boolean
 //or do this
let fileExists = existsSync("./notes"); 
console.log(fileExists);// returns boolean

Check that a file exists (ensureFile)

ensureFile ensures that a file exists.

Let’s write a simple program to experiment with it:

import { ensureFile, ensureFileSync } from "https://deno.land/std/fs/mod.ts";
let ok = ensureFileSync("./read.ts");

If the file does not exist, Deno automatically creates it. Again, remember to add the --unstable flag since some of these methods are still experimental.

How to empty a directory in Deno (emptyDir)

The emptyDir method checks if a directory is empty. If the specified directory contains any file or directory, Deno empties the directory.

import { emptyDir } from "https://deno.land/std/fs/mod.ts";

emptyDir("./notes").then((res) => console.log("res", res)); // this method return a promise.

Creating a CLI application in Deno

Now let’s create a simple CLI application that will create files for us. We’ll use the terminal to create this file.

Deno.args returns all the arguments passed in a command. With this, we can create a simple application. Our command will hold the name of the file we want to create.

Run the following:

deno run main.ts create-file test.ts.

This command has two arguments: create-file and test.ts. If we log Deno.args, it will return the arguments in an array.

We can use this to check whether the u

ser passed the create-file param and provided a name for a file:

let params = Deno.args;
console.log(params);
let createFile = () => {
  if (params[0] !== "create-file") {
    console.log(
      `${params[0]} is not a valid command, Did you mean 'create-file'`,
    );
    return false;
  } else if (!params[1]) {
    console.log(
      `You need to provide a name of a file`,
    );
    return false;
  } else {
    Deno.writeTextFileSync(`./${params[1]}`, "//This is your created file");
  }
};
createFile();

Now to run the application, open up your terminal and run the following:

deno run --allow-all main.ts create-file <name of file>

Remember to add the --allow-all or --allow-write file flag.

Conclusion

As you can see, Deno’s file system is quite versatile, and there are multiple approaches and scenarios to consider when writing to a file to Deno. It’s always good to know how to use the synchronous and asynchronous methods as both have their use cases. When writing to larger files, you should consider taking advantage of the chunked writing capabilities of writing streams.

The source code used in this demo is available on GitHub.

Wisdom Ekpot A student of Ibom Metropolitan Polytechnic studying computer engineering, Wisdom has been writing JavaScript for two years, focusing on Vue.js, Angular, and Express.js.

Leave a Reply