Node.js | A File Watching Program and fs.appendFile()

Andrew Miller
3 min readJan 3, 2021
Photo by Timothy Meinberg on Unsplash

Welcome! Thanks for being here. Let’s make a file watching program, and have it watch a file for content changes. We will change the content of a file using a program that facilitates appending text via the process.stdin

We will make this program in two steps. First we are going to create a program that appends data from the process.stdin to a file. The program will create a file, if one doesn’t already exist.

File Name: append.js

1 "use strict";2 const { join } = require('path'); // file path builder3 const { appendFile } = require('fs'); // facilitates appending4 const writeInMe = join(__dirname,'writeInMe'); // The file we will write to. 5// logErr is passed as an argument to append to deal with potential errors.6 const logErr = (error) => error ?7                console.error(error) :8                null;9. // An event listener for the 'data' event is attached to the stdin.10 process.stdin.on('data', (data) => {11   appendFile(writeInMe, data, logErr); // the data is appended12 });     

When the program above is executed it creates a file named writeInMe. Then on line 10 it sets an event listener on the process.stdin. The event listener keeps the process alive, while waiting for data to be passed to stdin.

node append.js

Execute the file using the command above.

you will now be able to enter data into the process by typing on the keyboard. When you press enter the data will be appended to writeInMe because of our appendFile() function on line 11 of append.js.

Now if you want you can check your writings by entering the command:

cat writeInMe

And you can see all the data from that file displayed in the stdout.

Great! 😊

Lets watch the file writeInMe.

To do this we need to watch for file system events and check the file’s details using fs.stat() to determine what happend to the file. We must filter out events that are not a result of the files content being changed, and redundant events.

watch.js

1 "use strict";2 const { watch , stat} = require('fs'); // stat retrieves file details3 const { join} = require('path');  // file path builder4 const fileName = process.argv[2];  // second argument from the command line.5 const filesPath = join(__dirname, fileName );6 let recentEventTime; 7 watch(filesPath,(eventType,fileName) => {8   stat(filesPath, (error, stats) => {9     const { ctimeMs, mtimeMs } = stats;  // modify time, change time10     if (error) console.error(error)11     if (recentEventTime === ctimeMs) return null;12     if (ctimeMs === mtimeMs) {13       console.log(`I saw ${fileName}'s content get changed.`)14     }15     recentEventTime = ctimeMs;16   })17 });1819 console.log(`I am watching ${fileName}.`);

Now we need to write the command.

node watch.js writeInMe

writeInMe gets passed into process.argv[2] position and is used to construct the file path.

Now if we open a seperate terminal tab and run:

node append.js

We can append text to writeInMe, and each time we append text we will see

I saw writeInMe's content get changed.

Printed to the stdout of watch.js.

Let’s review how watch.js works.

The watch() function is passed the full path to writeInMe. It then starts listening for events, and each time writeInMe emits an event, the listener callback function is executed.

The stat() function retrieves information about the file, including the change time, ctimeMs and the modified time mtimeMs.

The ctimeMs is updated everytime the file has any kind of change, whether it be content or a permissions change. The mtimeMs is not updated if the content of the file is changed.

The logic we created filters out the events where the content is not modified, by only reacting when ctimeMs is strictly equal to mtimeMs.

Two events are emitted each time a file’s content is changed in this way. We created a variable called recentEventTime to filter out repetitive events.

That concludes this journey. Thanks for your time!

--

--

Andrew Miller

Hello I am Andrew Miller. I am a Software Engineer that loves Node.js