Categories
express file fs javascript node.js

Writing to files in Node.js

1952

I’ve been trying to find a way to write to a file when using Node.js, but with no success. How can I do that?

0

    2843

    There are a lot of details in the File System API. The most common way is:

    const fs = require('fs');
    
    fs.writeFile("/tmp/test", "Hey there!", function(err) {
        if(err) {
            return console.log(err);
        }
        console.log("The file was saved!");
    }); 
    
    // Or
    fs.writeFileSync('/tmp/test-sync', 'Hey there!');
    

    13

    • 34

      I’ve tested this script using Node, and I tried changing the file path to “/home/”, but I got the following error: { [Error: EACCES, open '/home/test.txt'] errno: 3, code: 'EACCES', path: '/home/test.txt' } How can I modify this script so that it will work outside of /tmp?

      Sep 10, 2012 at 20:37


    • 152

      Also note you can use fs.writeFileSync(…) to accomplish the same thing synchronously.

      Jan 23, 2013 at 18:28

    • 9

      Maybe it’s a bit old, but @AndersonGreen, you need to run node as root or chmod /home properly to allow R/W permissions to current node process owner (your username tough) so you can write the file

      Jan 2, 2014 at 23:34

    • 45

      Actually, @DenysVitali, the problem is that jane should not be able to write any files into /home/.... Generally that directory is 755 root:wheel (or whatever). If node wants to write a file as jane, it’s going to be easier to write to /home/jane/test.txt. Changing /home to something more permissive than 755 is a huge mistake.

      – jane arc

      Jan 26, 2014 at 23:05

    • 11

      @JaneAvriette Well, since he wanted to save the file on /home directory I suggested to chmod it. I know it could generate a security issue. But well, if the user wants to save there, that’s the solution. P.S: I agree with what you said (:

      Jan 29, 2014 at 22:51

    605

    Currently there are three ways to write a file:

    1. fs.write(fd, buffer, offset, length, position, callback)

      You need to wait for the callback to ensure that the buffer is written to disk. It’s not buffered.

    2. fs.writeFile(filename, data, [encoding], callback)

      All data must be stored at the same time; you cannot perform sequential writes.

    3. fs.createWriteStream(path, [options])

      Creates a WriteStream, which is convenient because you don’t need to wait for a callback. But again, it’s not buffered.

    A WriteStream, as the name says, is a stream. A stream by definition is “a buffer” containing data which moves in one direction (source ► destination). But a writable stream is not necessarily “buffered”. A stream is “buffered” when you write n times, and at time n+1, the stream sends the buffer to the kernel (because it’s full and needs to be flushed).

    In other words: “A buffer” is the object. Whether or not it “is buffered” is a property of that object.

    If you look at the code, the WriteStream inherits from a writable Stream object. If you pay attention, you’ll see how they flush the content; they don’t have any buffering system.

    If you write a string, it’s converted to a buffer, and then sent to the native layer and written to disk. When writing strings, they’re not filling up any buffer. So, if you do:

    write("a")
    write("b")
    write("c")
    

    You’re doing:

    fs.write(new Buffer("a"))
    fs.write(new Buffer("b"))
    fs.write(new Buffer("c"))
    

    That’s three calls to the I/O layer. Although you’re using “buffers”, the data is not buffered. A buffered stream would do: fs.write(new Buffer ("abc")), one call to the I/O layer.

    As of now, in Node.js v0.12 (stable version announced 02/06/2015) now supports two functions:
    cork() and
    uncork(). It seems that these functions will finally allow you to buffer/flush the write calls.

    For example, in Java there are some classes that provide buffered streams (BufferedOutputStream, BufferedWriter…). If you write three bytes, these bytes will be stored in the buffer (memory) instead of doing an I/O call just for three bytes. When the buffer is full the content is flushed and saved to disk. This improves performance.

    I’m not discovering anything, just remembering how a disk access should be done.

    6

    • 7

      +1 – nice explanation. For write stream, it’s important to read the docs carefully. If returns false or closing, important to call writer.once(‘drain’, function(){}) or I missed lines that hadn’t drained when the process ended.

      – bryanmac

      Jun 19, 2014 at 15:18

    • 4

      any chance you could provide an example of how to use cork() and uncork() for those of us who want to try out the pre-release 0.11 node?

      Aug 16, 2014 at 7:05

    • As of now, Node v0.12 is stable.

      – aug

      Apr 1, 2015 at 5:41

    • According to an analysis of code from GitHub, fs.writeFile seems to be the most popular of the functions you mentioned. Here are real world examples for using fs.writeFile

      – drorw

      Apr 18, 2019 at 20:11

    • 1

      Are there production quality libraries on npm implementing buffered writing?

      – nponeccop

      May 12, 2019 at 18:48

    296

    You can of course make it a little more advanced. Non-blocking, writing bits and pieces, not writing the whole file at once:

    var fs = require('fs');
    var stream = fs.createWriteStream("my_file.txt");
    stream.once('open', function(fd) {
      stream.write("My first row\n");
      stream.write("My second row\n");
      stream.end();
    });
    

    9

    • 22

      What is the ‘fd’ variable passed into the callback for stream.once ?

      Oct 18, 2012 at 5:49

    • 2

      @ScottDavidTesler file descriptor so you will be able to close stream after you’ve done with it.

      Nov 20, 2012 at 11:32

    • 3

      When do I close the stream? Why is this non-blocking? Just curious, I am trying to write to a log file.

      – MetaGuru

      Jan 3, 2013 at 3:06

    • 1

      I’m not sure if when the stream is flushed. My guess is that there is a possibility to flush the stream on demand.

      Apr 24, 2013 at 9:38

    • 2

      This example is leaving me with an empty “my_file.txt” and a dump of the WriteStream object.

      Apr 12, 2019 at 20:30