Node.js’s ‘fs’ Module: Writing Files and Directories
By: John Au-Yeung
Tags: Technology, Nodejs, Programming, JavaScript, Software Development

fs.Write

There are two versions of the write functions, one for writing text to disk and another for writing binary data to disk.

The text version of write function lets us write text onto the disk asynchronously. It takes a few arguments.

The first argument is the file descriptor — a number that identifies the file.

The second argument is a string that’s written to the file. If the value passed in is not a string, it is converted to one.

The third argument is the position in which the file writing starts. If the value passed in isn’t a number, then it starts in the current position.

The fourth argument is a string that has the character encoding of the file to be written, which defaults to be utf8 . The last argument is a callback function with three parameters.

The first is the err object which has the error object and it’s not null if there’s an error.

The second parameter is the written parameter, an integer which specifies how many bytes are written to the file system. It’s not necessarily the same as the number of string characters written.

The third parameter is the string parameter that has the string that was written.

On Linux, positional writes don’t work in the append model. On Windows, if the file descriptor is 1, which stands for the standard output, then strings that have non-ASCII characters won’t be rendered properly by default.

To use the write function, we can use the open function to get the file descriptor of the file you want to write to first, then we can write to the file by passing in the file descriptor to the write function. For example, if we want to write to the file with the path ./files/file.txt , we can write something like this:

const fs = require("fs"); fs.open("./files/file.txt", "r+", (err, fd) => {

if (err) throw err;

fs.write(fd, "abc", 0, "utf8", (err, written, string) => {

console.log(err, written, string);

fs.close(fd, err => {

if (err) throw err;

});

});

});

When we run the code above, we should get output that looks something like this:

null 3 abc

In the code above, we first open the file with the open function. We pass in the r+ flag so that we can write to the file. Then we get the file descriptor fd in the callback function that we passed into the open function. With the fd file descriptor, we can pass it into the write function.

In the second argument of the write function we specified that we want to write the string abc to the file. In the third argument, we specified that we want to write it at position 0, the fourth argument specifies that the character encoding of the string should be UTF-8.

The callback in the last argument would get us the result of the write. From there, we know from the output that three bytes and the string ‘abc’ were written to the file.

Other than the r+ flag, there are many other possible system flags, including:

'a' — Opens a file for appending, which means adding data to the existing file. The file is created if it does not exist.

— Opens a file for appending, which means adding data to the existing file. The file is created if it does not exist. 'ax' — Like 'a' but an exception is thrown if the path exists.

— Like but an exception is thrown if the path exists. 'a+' — Open file for reading and appending. The file is created if it doesn’t exist.

— Open file for reading and appending. The file is created if it doesn’t exist. 'ax+' — Like 'a+' but an exception is thrown if the path exists.

— Like but an exception is thrown if the path exists. 'as' — Opens a file for appending in synchronous mode. The file is created if it does not exist.

— Opens a file for appending in synchronous mode. The file is created if it does not exist. 'as+' — Opens a file for reading and appending in synchronous mode. The file is created if it does not exist.

— Opens a file for reading and appending in synchronous mode. The file is created if it does not exist. 'r' — Opens a file for reading. An exception is thrown if the file doesn’t exist.

— Opens a file for reading. An exception is thrown if the file doesn’t exist. 'r+' — Opens a file for reading and writing. An exception is thrown if the file doesn’t exist.

— Opens a file for reading and writing. An exception is thrown if the file doesn’t exist. 'rs+' — Opens a file for reading and writing in synchronous mode.

— Opens a file for reading and writing in synchronous mode. 'w' — Opens a file for writing. The file is created (if it does not exist) or overwritten (if it exists).

— Opens a file for writing. The file is created (if it does not exist) or overwritten (if it exists). 'wx' — Like 'w' but fails if the path exists.

— Like but fails if the path exists. 'w+' — Opens a file for reading and writing. The file is created (if it does not exist) or overwritten (if it exists).

— Opens a file for reading and writing. The file is created (if it does not exist) or overwritten (if it exists). 'wx+' — Like 'w+' but an exception is thrown if the path exists.

The binary version of the write function lets us write text onto the disk asynchronously. It takes a few arguments.

The first argument is the file descriptor which is a number that identifies the file.

The second argument is the buffer object which can be of type Buffer, TypedArray or DataView.

The third argument is the offset , which determines the part of the buffer to be written.

The fourth argument is the length argument that specifies the number of bytes being written, the last argument is the position which is an integer which describes the position in which the write function will start writing.

The final argument is a callback function — a function that takes the err parameter, which has the error object. If an error occurs, the second is the bytesWritten parameter which gets us the number of bytes written to disk, the third is the buffer object, which has the binary data which was written to disk.

For example, we can use it as in the following code:

const fs = require("fs"); fs.open("./files/binaryFile", "w", (err, fd) => {

if (err) throw err;

fs.write(fd, new Int8Array(8), 0, 8, 0, (err, bytesWritten, buffer) => {

console.log(err, bytesWritten, buffer);

fs.close(fd, err => {

if (err) throw err;

});

});

});

We get the following output if we run it: