Assess and Choose Three Approaches to Reading from the File System in Node.js

Share this video with your friends

Social Share Links

Send Tweet

There are a handful of ways you can read and write to the File System in Node.js.

We will look at readFileSync, readFile, and a promise based version of readFile.

Each have there use-cases and we will discuss the pros and cons of each one. For instance readFileSync is a blocking operation which if you were developing a web server with Node.js would be a huge problem. With this project being in the CLI for one user, this is a ok option to consider. On the other hand, readFile is a non-blocking operation that uses promises/callbacks to interact with the file system.

Kevin Cunningham: [0:00] My data source is going to be this data.json file, which is currently just an empty array. I want to be able to use Node to open that file, do some work with it, and write to it. Fs is the Node file system module, so I'm going to import fs. Let's look at three different ways to read and parse that file. [0:20] The first is with readFileSync. This is a synchronous operation, which means it will block the JavaScript event loop until this file has been returned from the file system and is read fully into memory. For small files, it's not a huge deal, but this is a blocking operation.

[0:37] This is a web server. readFileSync is stopping your Node instance from listening to any other incoming requests. We're writing a local command line tool, and the readFileSync might be the most appropriate way through. It's going to take the path, data.json, and it's going to return the contents of that file as a buffer. If I console.log(contents), we'll see we get this buffer, 5b and 5d.

[1:06] We can get the string representation of any buffer with the two-string method, and then we can convert it into a JavaScript object by using JSON.parse. This is open square brackets, close square brackets, the string. This is open square brackets, close square brackets, the array.

[1:24] ReadFileSync, fine for a single user CLI tool, but it's blocking and it's dangerous. We probably should avoid that.

[1:35] What's the next way we could do this? The next thing we could do is use a callback. fs.readFile() is a callback-based API. Again, it takes the path to the file and then it takes an error-first callback. We get the error first and then the contents.

[1:54] This is a really common pattern in Node callback APIs where we get the error and we cast if there is an error. If there is an error, we do something with it. Maybe we'll console.log(error) and then we will exit, so process.exit with a non-zero exit code.

[2:13] Otherwise, we will do exactly what we had up here. That line will stay the same. We got the contents, two string and we're parsing them. If we run this, we should get exactly the same result. Brilliant.

[2:24] This is non-blocking, which means that if this file takes a while to open, our Node process is able to do other work. Once the file is opened, this callback function will be executed with the data. This is better because it's asynchronous, but better again is to lean on Promises and async/await.

[2:44] In our import statement, instead of fs from 'fs', I'm going to do /Promises, which imports the Promises-based APIs from file system. Now I can do something very similar. I can do const contents = fs.readFile, and that takes a path.

[3:05] This is an asynchronous operation, so I'm going to need to await it. I can use this again, the same logging line. This had error handling, so let's add error handling in here as well.

[3:18] We'll stick this in a try...catch, we'll bring these lines in here, and then we'll do the same thing we said earlier. If there is an error, we'll console.log(error) and then exit. Let's make there be an error. Let's make the file not exist, then we get our error logged and we've exited.

[3:36] This method is asynchronous using async/await from Promises. You can have good error handling under the approach that we are going to use through the development of our API.