Although Node.js may at first glance appear to be just another JavaScript library, in fact, it’s really a server-side runtime environment built on Chrome’s V8 JavaScript engine. Running on the server provides a lot of advantages over traditional JavaScript that executes within the confines of the browser. One such advantage is access to the file system. As a matter of fact, Node.js provides an entire module dedicated to file system operations. In today’s article, we’ll try out a few of them.
A Brief Overview
The file system module (fs) is part of Node’s core modules so all you need to do to use it is use the require() method:
var fs = require('fs');
Some common uses for the File System module:
- Watch folders for changes
- Obtain Folder and File statistics
- Set/change file modes
- Work with directories
- Create URLs
With regards to file operations, you can:
- Read files
- Create files
- Update files
- Delete files
- Rename files
Reading a File
The easiest way to read a file in Node.js is to use the fs asynchronous – a.k.a. non-blocking – readFile() method. It simply reads in the entire file at once and passes on the data to a callback function when done. Here’s part of a file of movie data:
"film_id","title","description","release_year","rental_rate","length","rating" "1","ACADEMY DINOSAUR","A Epic Drama of a Feminist…","2006","0.99","86","PG" "47","BABY HALL","A Boring Character Study of a A Shark…","2006","4.99","153","NC-17" "110","CABIN FLASH","A Stunning Epistle of a Boat And…","2006","0.99","53","NC-17" "202","DADDY PITTSBURGH","A Epic Story of a…","2006","4.99","161","G"
This code reads in the file and spits it out to the console:
var fs = require('fs'); fs.readFile('sakila videos.csv', function (err, data) { if (err) throw err; if (data) { console.log(data.toString('utf8')); } });
Most file methods have an equivalent synchronous – a.k.a. blocking -version. These end in “Sync”; hence, readFile’s synchronous counterpart is readFileSync. Here’s the code to use it:
var fs = require('fs'); var movies = fs.readFileSync('sakila videos.csv', 'utf8'); console.log(movies);
Writing a File
Let’s switch gears now and create a file.
The writeFile method writes data to files asynchronously, and invokes a callback function once the write operation completes.
Here is a simple example that writes some song lyrics to a file:
var lyrics = 'Wind in my hair -n' + 'Shifting and drifting -n' + 'Mechanical music -n' + 'Adrenalin surge -'; // write to a new file fs.writeFile('red barchetta.txt', lyrics, function (err) { // rethrows an error, you could also catch it here if (err) throw err; // success case, the file was saved console.log('Lyric saved!'); });
The writeFile method’s synchronous equivalent is writeFileSync. Here’s the above example in synchronous style:
var lyrics = 'Wind in my hair -n' + 'Shifting and drifting -n' + 'Mechanical music -n' + 'Adrenaline surge -'; // write to a new file fs.writeFileSync('red barchetta.txt', lyrics);
Simple!
Just be careful when using these two methods because they will create a new file every time; in other words, they’ll clobber any pre-existing file of the same name!
Up until quite recently, you could use the fs.exists() method to check for the existence of a file before the write operation. However, it has now been deprecated because fs.exists’ callback argument accepted parameters that were inconsistent with other Node.js callbacks. Interestingly, exists’ existsSync companion method is still OK to use because it does not use a callback. Having said that, calling existsSync() before fs.open(), fs.readFile() or fs.writeFile() is not recommended as doing so introduces a race condition, since other processes may change the file’s state between the two calls. The preferred approach is to open/read/write the file directly and handle the error raised if the file does not exist. Here’s how we could make sure that our lyrics file isn’t produced if there’s already one there:
var filename = 'red barchetta.txt', lyrics = 'Wind in my hair -n' + 'Shifting and drifting -n' + 'Mechanical music -n' + 'Adrenaline surge -'; fs.open(filename, 'wx', function(err, fd) { if (err) { if (err.code === 'EEXIST') { console.error(`'filename' already exists!`); return; } throw err; } fs.write(fd, lyrics, function(err, written, string) { if (err) throw err; console.log('Lyric saved!'); }); });
You can read more on the fs.write() method in the docs.
Conclusion
Node’s File System module is chock full of useful methods to assist you in working with the file system on your computer, in fact, many more that we explored here today. It’s definitely worth learning about!