How to Read and Write Text Files (.txt) in Node.js

Updated: December 28, 2023 By: Guest Contributor Post a comment

Overview

Node.js is a powerful JavaScript runtime built on Chrome’s V8 engine. It provides a rich set of filesystem operations through its ‘fs’ module, which can be used to perform tasks such as reading from and writing to text files. This tutorial will guide you through the basics of file handling in Node.js, including reading and writing text files using synchronous and asynchronous approaches.

In Node.js, the ‘fs’ module handles file operations. We have two main patterns when working with ‘fs’: synchronous (blocking) and asynchronous (non-blocking). Choosing the right pattern is crucial for the performance of your Node.js application, especially under heavy I/O operations.

Let’s dive into the details and learn how to handle text files effectively in Node.js. We’ll begin with simple examples and gradually move on to more complex scenarios, including error handling and working with streams.

Reading Text Files Synchronously

const fs = require('fs');

const data = fs.readFileSync('/path/to/file.txt', { encoding: 'utf8' });
console.log(data);

The code above uses fs.readFileSync to read the contents of a file and print them to the console. The method is simple and blocks the rest of your code from executing until the file is fully read.

Reading Text Files Asynchronously

const fs = require('fs');

fs.readFile('/path/to/file.txt', { encoding: 'utf8' }, (err, data) => {
  if (err) throw err;
  console.log(data);
});

This snippet demonstrates the async nature of fs.readFile. Node.js can continue executing the rest of the code while the file is being read. The callback function handles the contents of the file once the reading is complete.

Writing to Text Files Synchronously

const fs = require('fs');

const content = 'Hello, World!';
fs.writeFileSync('/path/to/file.txt', content);
console.log('File written successfully');

To write to a file synchronously, fs.writeFileSync method is used. It takes the path to the file and the content to write. Once the file is written, the message is printed to the console.

Writing to Text Files Asynchronously

const fs = require('fs');

const content = 'Hello, Node.js!';
fs.writeFile('/path/to/file.txt', content, (err) => {
  if (err) throw err;
  console.log('File written successfully');
});

The fs.writeFile method is the asynchronous counterpart to fs.writeFileSync. You can pass a callback that gets invoked once the writing is finished.

Advanced Topics: Streams and Buffering

When dealing with large files, streams can be a more efficient way of reading from or writing to files. Streams allow you to process the file in chunks, reducing the memory footprint.

const fs = require('fs');
const { ReadStream, WriteStream } = require('fs').promises;

async function streamReadWrite() {
  let readStream = fs.createReadStream('/path/to/large-file.txt', { encoding: 'utf8' });
  let writeStream = fs.createWriteStream('/path/to/new-file.txt');

  readStream.on('data', function(chunk) {
    writeStream.write(chunk);
  });

  readStream.on('end', function() {
    writeStream.end();
    console.log('Stream finished.');
  });
}

streamReadWrite();

The code above demonstrates the use of streams to read from one file and write to another. It leverages events like ‘data’ to read chunks and ‘end’ to know when the reading is complete.

Error Handling in File Operations

Error handling is an essential part of working with files. When performing asynchronous file operations, always handle the errors in your callback function. Similarly, for synchronous methods, use try-catch blocks to handle exceptions.

const fs = require('fs');

try {
  const data = fs.readFileSync('/path/to/non-existent-file.txt', { encoding: 'utf8' });
  console.log(data);
} catch (err) {
  console.error('An error occurred:', err.message);
}

Conclusion

In this tutorial, we’ve explored the fundamentals of reading and writing text files in Node.js using both synchronous and asynchronous methods, including streams and effective error handling. With these tools, you can manage file I/O operations within your Node.js applications smoothly and efficiently.

As you apply these techniques to your own projects, remember to consider the I/O operation’s nature and the application’s requirements to choose the most suitable reading or writing method. Use stream-based operations for larger files to prevent memory overflow and ensure that your application remains responsive.

With the power of Node.js, you’re well-equipped to tackle a wide range of filesystem tasks, enhancing the functionality and performance of your applications. Happy coding!