NodeJS is an awesome platform to build applications in javascript which can run on the server.
It allows you to read n write to files asynchronously and synchronously
Writing Data to files
The easiest way would be write synchronously (i.e. wait till the writing operating is finished)
var fs = require('fs'); fs.writeFileSync('/path/to/some_text.txt', 'some text');
But the preferable way of writing to files will be asynchronous in context of web apps.
var fs = require('fs'); fs.writeFile("/path/to/some_text.txt", "test data!", function(err) { if(err) { console.log(err); } else { console.log("file has been saved successfully"); } });
In this case the program will continue to execute next instruction without waiting for the file write to complete. Once the file writing is completed, the third parameter (closure ) is executed. Above method overwrite the current file. So if you want to append the data, use
appendFile
(async) and
appendFileSync
for synchronous appending data to file.
Reading Files
Like writing you can read files
synchronously
var FS = require ( 'FS' ); var text = FS . readFileSync ( 'path/to/test_text.txt' , 'utf8' );
As you can guess the second parameter here is the encoding. If it is not passed the function returns a
buffer
For reading
asynchronously
fs.readFile('path/to/test.txt', {encoding: 'utf8'}, function (err, data) { if (err) throw err; console.log(data); });
Similar to the synchronous function you need to pass the encoding, otherwise you get the data buffer instead of text.
Optimizing reading and writing using File Streams / threads
Log files or other automatically generated files normally are of few mbs in size and can even reach Gb. Above functions
readFile
and
writeFile
works well for small files but becomes bottleneck when the filesize grows large because both of above methods load all the content of the file into memory. Threads/Streams come to our rescue when we need to deal with larger files.
var fs = require('fs'); var stream = fs.createReadStream('path/to/test.txt', {encoding: 'utf8'}); stream.on('readable', function() { var buf; while ((buf = stream.read()) !== null) { console.log(buf); } }); Stream.once( 'end' , function () { console.Log( 'Read completed successfully.' ); });
The above function opens the file and when the file is ready to be read, the event
readable
is fired, and code in the
closure
is executed which reads the file till the end. Here we are only reading few bytes / kbs of data from the file at a time. You can customize this by passing no of bytes to read as
stream.read(2048)
Now for writing to files with streams
var fs = require('fs'); var writer = fs.createWriteStream('test.txt', {flags: 'w'}); writer.on('finish', function() { console.error('data has been saved successfully'); }); var i = 0; function write() { do { var ok = writer.write('test, #' + i + '!\n'); if (!ok) { writer.once('Drain', write); break; } i++; } while (i < 10 && ok); if (i === 10) { writer.end('===== end =====\n'); } } write();
The above code writes to the file 10 lines. When it is not successful, it schedules a listener to wait for event
Drain
which indicates that the file is writeable and writes the data.
We can use read & write data streams to copy data from one file to another using the stream property
pipe
which can be called on the source stream (reader) and pass the target stream writer as input to save data.
var fs = require('fs'); var source = fs.createReadStream('file1.txt'); var target = fs.createWriteStream('file2.txt'); source.pipe(target);
In the above code we save the data in
file2.txt
as soon as we read data from
file1.txt
Now if you need to transform/change the data while copying you can use the
Transform
function of the
Stream
in combination with
pipe
.
var fs = require('fs');
var Transform = require('stream').Transform;
var uppercase = new Transform({decodeStrings: false});
uppercase._transform = function(chunk, encoding, done) {
done(null, chunk.toUpperCase());
};
var source = fs.createReadStream('file1.txt', {encoding: 'utf8'});
var target = fs.createWriteStream('file2.txt');
source.pipe(uppercase).pipe(target);
The above code transforms the text in
file1.txt
to
uppercase
and saves in
file2.txt
Thats all for now folks. This is as broad as we can cover in a single tutorial. Hope this helps. For more information please visit the official documentation.
Ref: Чтение и запись файлов в NodeJS
http://nodejs.org/api/fs.html