Writing to files in Node.js
Solution 1
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!');
Solution 2
Currently there are three ways to write a file:
-
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.
-
fs.writeFile(filename, data, [encoding], callback)
All data must be stored at the same time; you cannot perform sequential writes.
-
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.
Solution 3
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();
});
Solution 4
Synchronous Write
fs.writeFileSync(file, data[, options])
fs = require('fs');
fs.writeFileSync("foo.txt", "bar");
Asynchronous Write
fs.writeFile(file, data[, options], callback)
fs = require('fs');
fs.writeFile('foo.txt', 'bar', (err) => { if (err) throw err; });
Where
file <string> | <Buffer> | <URL> | <integer> filename or file descriptor
data <string> | <Buffer> | <Uint8Array>
options <Object> | <string>
callback <Function>
Worth reading the offical File System (fs) docs.
Update: async/await
fs = require('fs');
util = require('util');
writeFile = util.promisify(fs.writeFile);
fn = async () => { await writeFile('foo.txt', 'bar'); }
fn()
Solution 5
var path = 'public/uploads/file.txt',
buffer = new Buffer("some content\n");
fs.open(path, 'w', function(err, fd) {
if (err) {
throw 'error opening file: ' + err;
}
fs.write(fd, buffer, 0, buffer.length, null, function(err) {
if (err) throw 'error writing file: ' + err;
fs.close(fd, function() {
console.log('file written');
})
});
});
Gjorgji
Updated on July 22, 2022Comments
-
Gjorgji almost 2 years
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?
-
Anderson Green over 11 yearsI'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
? -
Scott Tesler over 11 yearsWhat is the 'fd' variable passed into the callback for stream.once ?
-
Alexey Kamenskiy over 11 years@ScottDavidTesler file descriptor so you will be able to close stream after you've done with it.
-
MetaGuru over 11 yearsWhen do I close the stream? Why is this non-blocking? Just curious, I am trying to write to a log file.
-
Fredrik Andersson over 11 yearsYou can always do a stream.end() when you've done your stream.writes(). I will add it to the example.
-
David Erwin over 11 yearsAlso note you can use fs.writeFileSync(...) to accomplish the same thing synchronously.
-
Automatico about 11 yearsWill this fail if the server goes down before stream.end() is called? In essence, can I use this for error logging to specific file? (Yes, I know you can specify this when you run the node app, but for certain errors I want to store it in a different file than all the other logging).
-
Fredrik Andersson about 11 yearsI'm not sure if when the stream is flushed. My guess is that there is a possibility to flush the stream on demand.
-
Jo Liss over 10 yearsDoes the 'open' event happen asynchronously? Do I have to wait for it, or can I start writing into the stream immediately?
-
Denys Vitali over 10 yearsMaybe 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
-
jane arc over 10 yearsActually, @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. -
Denys Vitali over 10 years@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 (: -
Robbie Smith almost 10 yearsI'm trying to do this to an ascii based file and null characters are getting inserted into every other character. Advice?
-
bryanmac almost 10 years+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.
-
professormeowingtons almost 10 yearsany chance you could provide an example of how to use
cork()
anduncork()
for those of us who want to try out the pre-release 0.11 node? -
Fredrik Andersson over 9 years@JoLiss You will have to wait for it.
-
Kai Feng Chew over 9 yearsWhere to find the file helloworld.txt ? I can't find it in any folders... thanks.
-
Sérgio over 9 yearsin folder that you run the script
-
Kai Feng Chew over 9 yearsThat's weird... I just can't find it anywhere. Will it be hidden? thanks again~
-
Kai Feng Chew over 9 yearsI just found it. Using this ROOT_APP_PATH = fs.realpathSync('.'); console.log(ROOT_APP_PATH); to get my where the file written. Thanks.
-
Sean Glover over 9 yearsthis demonstrates how to write a file using lower level fs operations. for example, you can guarantee when the file has finished writing to disk and has released file descriptors.
-
aug about 9 yearsAs of now, Node v0.12 is stable.
-
Adam Johns over 8 yearsDo you need to
fs.close()
when finished? -
Green over 7 years
This modules is created to save and remove files.
. Not an answer. -
nasch about 7 yearsAt least with ECMAScript 6,
fs.writeFile
is deprecated. Not sure what has replaced it. -
Ravi Shanker Reddy about 7 yearsWhere you are writting the data into the "to.text"??
-
Константин Ван over 6 years
-
Freewalker over 6 yearsOr ES2015 async/await style:
await promisify(fs.writeFile)("./test.md", markdownFile);
-
Amir over 5 years@Sérgio: do we need to close writefile? I am calling another process and I am receiving an error msg regarding file is begin used by some other process.
-
Tamer about 5 yearssingle quote in the string should be escaped.
-
Ron Jensen about 5 yearsThis example is leaving me with an empty "my_file.txt" and a dump of the WriteStream object.
-
drorw about 5 yearsAccording 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
-
TrevTheDev about 5 years@jgraup: are you using the latest version of node?
-
jgraup about 5 yearsNode
v10.15.0
-
TrevTheDev about 5 years@jpraup - latest is Node 12.
-
jgraup about 5 yearsI would just add the requirements in your answer or a note about the warning. The docs say
Added in: v10.0.0
so I would assume it could be used but I see elsewhere on here that people have opted to suppress the warning. -
nponeccop about 5 yearsAre there production quality libraries on
npm
implementing buffered writing? -
lte__ almost 5 yearsI'm trying to do this but I get
Uncaught ReferenceError: require is not defined
... -
Zimano over 4 yearsEnclosing function has to be async or this will not work.
-
Zimano over 4 yearsWhy are these snippets and not pieces of code? They will never be able to run in a browser anyways.
-
Timo Ernst over 4 yearsIt's always refreshing to see how easy this is using Node compared to languages like Java #FileOutputStreamWhatEverIntefaceBlah
-
Dan Dascalescu over 4 yearsThis introduces all sorts of complications (MongoClient, JSON etc.) that do not pertain to the question.
-
Dan Dascalescu over 4 years
-
Dan Dascalescu over 4 yearsWhat does this answer add to the multiple already existing answers about
writeFile
? -
Dan Dascalescu over 4 years
writeFile
had already been given as an answer multiple times, years ago. What does this answer add? -
Michal over 4 yearsAlso why od you open file? Shouldn't the answer be about writing files?
-
Manfred over 4 yearsSince in this example the offset if set to '0' (= third parameter of
fs.write()
) this example works only if everything is short enough to be written in a single write call. -
Manfred over 4 yearsSince it's now available I'd recommmend using
const
instead ofvar
, i.e.const fs = require('fs');
, to avoid unwanted side effects, in particular if you are working with a somewhat larger code base. -
Manfred over 4 years@Zimano As I understand it the question was regarding nodejs so doesn't need to be able to run in a browser.
-
Zimano over 4 years@Manfred Exactly! I think you misunderstood what I was trying to say; there is no point in having snippets since it is nodejs!
-
wintercounter about 4 years@Zimano Node already has support for top-level await, you don't need async wrapper.
-
Alex G almost 3 yearsI have tested createWriteStream on nodejs 14 and it is a lot faster than individual writes. also cork and uncork didn't affect the performance.
-
Elliott Jones almost 3 years@lte_ What environment are you running it in? If you're running it in the browser you'll definitely get that error. the answer here explains it best.