Create a File with Node.js

Node.js makes it possible to interact with your operating system filesystem, like reading from a file, deleting a file, updating a file, amongst others. Today, we look at various methods in the Node.js file system module that makes it possible to create a file.

N.b: Most of the methods come in 3 forms, synchronous, callback and promise. N.b: To use the file system module, we need to import it. An example is shown below.

const fs = require('fs') 
// For methods which are synchronous or requires a callback
// or 
const fsPromises = require('fs').promises 
// for methods which returns a promise.

N.b: The term __dirname is a variable that returns the directory name where the current Node.js file running it resides. __dirname does not need to be imported.

This article will require that you have a code editor and Node.js installed on your system. You can create a file with a .js extension. To run the code, from your terminal pointing at the root folder where your file is you run node <YOUR-FILE-NAME>.js.

The Open Method

The open method accepts the file path as a required argument and returns a file descriptor(fd).

A file descriptor is a number assigned to an open file by the operating system in memory. This number is later used to identify and track this file. The open method is needed to be called first when calling methods that require the file descriptor, like the read and write method etc.

To create a file using the open method, we need to pass in the path in which the file is located and the flag. The flag tells the open method why it needs to open the file. A list of available flags and use cases can be found here file system flags. The flags are in three groups, writing, reading and appending. To create a file we need to use the flags for writing and appending. The append and write flag will create the file if it does not exist. By default, the open method uses the read flag.

The open method will not create a non-existing folder. Ensure that the file is located in the last know folder.

fs.openSync()

This method is synchronous

  • An example using the write flag.
let fd = fs.openSync(__dirname + '/mew.txt', 'w')

console.log('fd ==> ', fd)

fs.open()

This method is asynchronous and requires a callback function

  • An example using the append flag.
fs.open(__dirname + '/mewe.txt', 'a', (err, fd) => {
    if (err) console.log('err ==> ',err);
    if (fd) console.log('fd ==> ', fd)    
})

fsPromises.open()

This method returns a promise object, which resolves to an instance of the FileHandle object. The fileHandle is a wrapper for the integer file descriptor and contains a close method. Always close the fileHandle.

  • An example with the async-await keyword.
async function createFile() {
    let fileHandle
    try {
        fileHandle = await fsPromises.open(__dirname + '/mow.txt', 'a')        
        console.log('fileHandle ==> ', fileHandle)
    } catch (err) {
        console.log('err ==> ', err)
    } finally {
        await fileHandle.close()
    }
}

createFile()

The CreateWriteStream Method

The fs.createWriteStream method creates an instance of fs.writeStream and returns the instance. It comes only in synchronous form.

To create a file with fs.createWriteStream we only need to pass the file path. The file path like fs.open should be in existence, as it only creates a new file. Passing the file descriptor in the options means the file is in existence. The method will ignore the file path and use the file descriptor. At its default state, a non-existing file is created and an existing file is overwritten.

The createWriteStream function behaviour can be slightly altered by setting the options part of the method. fs.createWriteStream(path, {options})

fs.createWriteStream()

const result = fs.createWriteStream(__dirname + '/meow.txt')
console.log('result ==> ', result)

The result variable will contain an instance of the writeStream object when successful and this contains all the methods and properties that can be called to take action on the file or get details of a file.

Other Methods

If you have gotten this far, Hurray. We considered two methods that can create a file, without needing the file content.

We are about to consider two methods for creating files that require passing in the file content.

The methods are:

  • fs.writeFile()
  • fs.appendFile()

They both have the three forms discussed earlier which are synchronous, callback and promise.

They also can accept a file descriptor if the file has been open for appending or writing. They both accept the file path and the data to be written to the file. If the file does not exist the file is created. fs.appendFile() will add to the contents of an existing file while fs.writeFile() overwrites the content of an existing file.

File system flags such as wx+ or wx for writing, and ax+ or ax for appending, can be added to ensure it fails if the file exists.

They both return undefined after executing.

When you pass the file content as an empty string '' it creates an empty file.

The WriteFile Method

The writeFile method by default, comes with the write flag w.

fs.writeFileSync()

This is a synchronous method.

fs.writeFileSync(__dirname + '/mew.txt', 'Can you keep a secret')

To ensure it does not overwrite an existing file we add one of the flags specified above.

fs.writeFileSync(__dirname + '/mew.txt', 'Can you keep a secret90', {flag: 'wx+'})

fs.writeFile()

This method accepts a callback function as its last argument.

fs.writeFile(__dirname + '/mew.txt', 'Can you keep a secret', {flag: 'wx'}, err => {
    console.log('err ==> ', err)
})

To ensure it does overwrite an existing file

fs.writeFile(__dirname + '/mew.txt', 'Can you keep a secret', err => {
    console.log('err ==> ', err)
})

fsPromise.writeFile()

This method returns a promise. In this example, we chain it with a then method and a catch method.

fsPromises.writeFile(__dirname + '/mew.txt', 'If walls could talk')
    .then(res => res)
    .catch(err => console.log(err))

A flag can be added as a third argument as shown in the previous example.

The AppendFile Method

This method by default comes with an a flag. This makes it possible to add content to an existing file. That is not the goal since we want to create a new file. Therefore all examples will contain flags that ensure that an exception is thrown if the file exists.

fs.appendFileSync()

This method is a synchronous method

fs.appendFileSync(__dirname + '/mew.txt', 'Truly Madly Deeply', {flag: 'ax'})

fs.appendFile()

This method accepts a callback function as its last argument.

const data = 'Do they know the places where we go when we are grey and old'
fs.appendFile(__dirname + '/mew.txt', data, {flag: 'ax+'}, err => console.log(err))

fsPromises.appendFile()

This method returns a promise

const data = 'I hope this finds a way to your heart.'

fsPromises.appendFile(__dirname + '/mew.txt', data, {flag: 'ax+'})
    .then(res => res)
    .catch(err => console.log(err))

Conclusion

This article looks at four methods that can create a file in Node.js and the various forms each method has. It discusses some side effects it has if an already existing file is been called to be created by the last two methods. The data written into the file in the last two methods were lines gotten from songs I was listening to while writing. I hope you enjoyed reading this.