learnyounode Lesson 3 – My First I/O!

In this exercise we need to create a program that reads a file synchronously and prints the number of new lines in the file to the console, similar to piping the cat command to word count count command to count the number of lines in a file.

cat myFile.txt | wc -l


If you aren’t familiar with these commands, cat reads a file and the pipe symbol ( | ) pipes the output of cat to the word count command (wc).  The line option (-l) counts the number of new lines in the file.

Let’s say these are the the contents of myFile.txt.


If we pipe the output of cat myFile.txt to the wc command, we get the result below.

cat myFile.txt | wc -l

Luckily, node has a filesystem module for performing tasks such as this.  To use it, we need to require the module so that we can use its methods.

var fs = require('fs')

After we require the fs module, we can use the readFileSync() method to read the contents of a file.  In this exercise, we want to read a file that is passed as the third argument on the command line.  Remember that in the baby steps exercise we used the argv property of the process object to sum values passed as argument.

We can access index 2 of process.argv to read the contents passed as the third argument to the command line.  The readFileSync() method returns the buffer object when the read is complete.

We can convert the contents of that buffer object to a string with the toString() method.  From there we can use the split() method to split the string at each new line (‘\n’) and get the length with .length.  Because our file will not will not have a new line delimiter at the end of the last line, we will end up with one extra new line in our count.  But we can just subtract one from our final value to get the correct count.  Is there a better way?  Probably, but you will have to do the heavy lifting to figure it out.

Official Solution

var fs = require('fs')  
var contents = fs.readFileSync(process.argv[2])  
var lines = contents.toString().split('\n').length - 1  

The solution is broken down into several lines for the sake of readability, but we can cram the solution into a single line if we want to.  However, this formatting may cause some to become nauseated, enraged, or both.  Use at your own risk.

console.log(require('fs').readFileSync(process.argv[2]).toString().split('\n').length - 1)

If we run either of these solutions from the command line, we will get the result that follows.

node ioSync.js myFile.txt

Thats it!

Lesson 4