# How to read and write files in Node.js

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published Aug 31, 2019, updated Aug 27, 2022. Topics: Node.js.
Canonical URL: https://attacomsian.com/blog/reading-writing-files-nodejs

> A practical guide to learning how to read and write files in Node.js using the native Filesystem module.

You can use the `fs` module to read and write files in Node.js. The `fs` module is a built-in module in Node.js that provides both asynchronous and synchronous functions to read, write, and watch files.

## Read Data From Files

The simplest way to read a file in Node.js is to use the `fs.readFile()` method by passing the file path, encoding, and a callback function. 

It asynchronously reads the entire contents of the file and calls the callback function with the file data:

```javascript
const fs = require('fs')

fs.readFile('file.txt', 'utf-8', (err, data) => {
  if (err) {
    throw err
  }
  console.log(data)
})
```

Alternatively, you can use  `fs.readFileSync()` to read the file synchronously:

```javascript
const fs = require('fs')

try {
  const data = fs.readFileSync('file.txt', 'utf-8')
  console.log(data)
} catch (err) {
  console.error(err)
}
```

> **Note:** If you skip the encoding parameter, a raw buffer is returned. Otherwise, a string is returned.

You can also use the [promise-based](https://attacomsian.com/blog/promises-javascript) `fsPromises.readFile()` method to read the file:

```javascript
const fsPromises = require('fs/promises')

const readFileAsync = async () => {
  try {
    const data = await fsPromises.readFile('file.txt', 'utf-8')
    console.log(data)
  } catch (err) {
    console.error(err)
  }
}

readFileAsync()
```

All the above three functions read the complete file contents in memory before calling the callback function and returning data. 

This means that if you are reading a large file, it might have an impact on your memory consumption and execution of the program.

For large files, it is better to use [streams](https://nodejs.org/api/stream.html) for reading the contents of a file.

## Write Data To Files

The easiest way to write data to files in Node.js is using the `fs.writeFile()` method. 

This method takes three parameters: the file path, the data to write, and a callback function, and writes the data asynchronously:

```javascript
const fs = require('fs')

const data = 'This is the new content of the file.'

fs.writeFile('file.txt', data, err => {
  if (err) {
    throw err
  }
  console.log('File is written successfully.')
})
```

Alternatively, you could use the `fs.writeFileSync()` to write the file synchronously:

```javascript
const fs = require('fs')

const data = 'This is the new content of the file.'

try {
  fs.writeFileSync('file.txt', data)
  console.log('File is written successfully.')
} catch (error) {
  console.error(err)
}
```

You can also use the promise-based `fsPromises.writeFile() ` method to write the file:

```javascript
const fsPromises = require('fs/promises')

const writeFileAsync = async () => {
  try {
    const data = 'This is the new content of the file.'
    await fsPromises.writeFile('file.txt', data)

    console.log('File is written successfully.')
  } catch (err) {
    console.error(err)
  }
}

writeFileAsync()
```

By default, the above methods override the file contents if it already exists. To append data to the file, you should pass a flag as the 3rd parameter:

```javascript
const fs = require('fs')

const data = 'Append this data at the end of the file.'

fs.writeFile('file.txt', data, { flag: 'a+' }, err => {
  if (err) {
    throw err
  }
  console.log('File is updated.')
})
```

Some of the flag options you can use:

* `r` &mdash; Open the file in read-only mode. An exception is thrown if the file does not exist.
* `r+` &mdash; Open the file for reading and writing. If the file does not exist, an exception is thrown.
* `w` &mdash; Open the file in write-only mode. The file is created (only if does not already exist) or truncated (if exists).
* `w+` &mdash; Open the file for reading and writing, placing the stream at the start of the file. The file is created if doesn't exist.
* `a` &mdash; Open the file for appending, positioning the stream at the end of the file. The file is created if doesn't exist.
* `a+` &mdash; Open the file for reading and appending, putting the stream at the end of the file. The file is created if it does not exist.

All the above methods continue writing to the file until the complete contents have been written before returning the control back to your program. 

If you are writing a lot of data, it might impact your application performance. In this case, a better approach would be to use a stream for writing to large files.

## Append Data To Files

Apart from flags, the `fs` module also provides `fs.appendFile()` (and `fs.appendFileSync()` for synchronous) method that asynchronously [append data to the file](https://attacomsian.com/blog/nodejs-append-data-to-file), creating the file if it does not yet exist:

```javascript
const fs = require('fs')

const data = 'Some data to append'

fs.appendFile('file.txt', data, err => {
  if (err) {
    throw err
  }
  console.log('File is updated.')
})
```

## Error Handling

If there is a runtime error while reading or writing to a file, the callback method is called with an `Error` object as the first argument. 

The simplest way to handle runtime errors is to throw them as Node.js exceptions like above. But this will crash the application and is therefore not recommended except in cases where you have no other choice:

```javascript
const fs = require('fs')

fs.readFile('404.txt', 'utf-8', (err, data) => {
  if (err) {
    console.error(err)
    // log the error here
  }
  console.log(data)
})
```

If you execute the above code, you will see the following output:

```bash
{ [Error: ENOENT: no such file or directory, open '404.txt'] 
    errno: -2, 
    code: 'ENOENT', 
    syscall: 'open', 
    path: '404.txt' }
undefined
```

## Further Reading

If you enjoyed reading this article, you might also like some of my other articles:

* [How to read and write JSON files in Node.js](https://attacomsian.com/blog/nodejs-read-write-json-files)
* [Reading a file line by line in Node.js](https://attacomsian.com/blog/reading-a-file-line-by-line-in-nodejs)
* [How to write a JSON object to a file in Node.js](https://attacomsian.com/blog/nodejs-write-json-object-to-file)
* [Uploading Files in Node.js and Express](https://attacomsian.com/blog/uploading-files-nodejs-express)
