The Filesystem
Reading and writing files on the filesystem (the hard drive) is a common asynchronous operation. Node.js provides both synchronous and asynchronous functions to read and write files. You can see this in the documentation for readFile
(the async promises version) and readFileSync
(the synchronous version). As you can see from the documentation for the fs
module, it provides a lot of functionality.
Filesystem access is part of a broader type of operations called IO, which stands for Input/Output. IO also includes accessing databases and communicating on a network. We're spending most of our time using the HTTP protocol when communicating over networks, but IO includes all protocols and data formats, and databases. All IO operations should be performed asynchronously because they often take much longer than performing the in-memory tasks most of our application is written to do.
Most of our web development work will not include operating on files. Most of it will involve databases and network communication. However, filesystem operations provide a great precursor into the asynchronous programming practices we'll apply with databases and networking, without having to understand the surrounding technology. The added benefit is understanding how to work with files, which is very handy when programming local scripts.
Reading a text file
To read a text file, we need the path to the file we want to read. In the example below, we're using the Path.Resolve
function to create the path to the students.json
file.
// Include modules provided by Node.jsimport * as fs from 'node:fs/promises'import * as Path from 'node:path'async function readAsync() {try{const studentsFile = Path.resolve('./storage/students.json')const contents = await fs.readFile(studentsFile, 'utf-8')console.log(contents)}catch(err: unknown){if (err instanceof Error) {console.error('Error reading file:', err.message);} else {console.error('Unknown error:', err);}}}
The contents of the file, contents
, will stored if the file was successfully read. If an error occurred we will instead log the error message.
Writing a text file
To write a text file, we need the path we want to create and the contents we want for the file.
// Include modules provided by Node.jsimport * as fs from 'node:fs/promises'import * as Path from 'node:path'async function writeAsync () {try{const teacherFile = Path.resolve('./storage/teacher.json')const teacherJson = JSON.stringify({ name: 'Don' })await fs.writeFile(teacherFile, teacherJson)console.log('File has been written to')}catch(err: unknown){if (err instanceof Error) {console.error('Error writing file:', err.message);} else {console.error('Unknown error:', err);}}}
The writeFile
function will accepts a string, which is returned from JSON.stringify
.