How to read files with Buffer & Stream in Node.js

There are two ways to read & write files; 1. buffer 2. stream

General Concept of Buffer and Streaming

  • Buffer or Buffering and Streaming is often used for video player in Internet such as Youtube

  • Buffering is an action to collect the data to play the video

  • Streaming is transmitting the data from server to the viewer’s computer

Concept of Buffer and Streaming in Node.js

Buffer and Stream in Node.js are actually similar to the general concepts

  • When reading a file, Node.js allocates memory as much as the size of a file and saves the file data into the memory

  • Buffer indicates the memory where file data resides

Buffer

image

Node.js has a internal buffer object called Buffer

const buffer = Buffer.from("Change me to buffer");
console.log("from()", buffer);
// from() <Buffer 43 68 61 6e 67 65 20 6d 65 20 74 6f 20 62 75 66 66 65 72>
console.log("length", buffer.length);
// length 19
console.log("toString()", buffer.toString());
// toString() Change me to buffer

const array = [
  Buffer.from("skip "),
  Buffer.from("skip "),
  Buffer.from("skipping "),
];
const buffer2 = Buffer.concat(array);
console.log("concat():", buffer2.toString());
// concat(): skip skip skipping

const buffer3 = Buffer.alloc(5);
console.log("alloc():", buffer3);
// alloc(): <Buffer 00 00 00 00 00>

**Buffer **object has many methods available

  • from() : Convert String to Buffer

  • toString() : Convert Buffer to String

  • concat() : Concatenate buffers in an array

  • alloc() : Create empty buffer in given byte length

Problem of Buffer

  • readFile() buffer method is convenient but has a problem that you need to create 100MB buffer in a memory to read 100MB file

  • If you read 10 100MB files, then you allocate 1GB memory just to read 10 files

  • Especially, it becomes a big problem for a server, given that you do not know how many people are going to use (read file) concurrently

Stream

image

Node.js has a internal stream method called createReadStream

readme3.txt

I am tranferring in bytes by bytes called chunk

createReadStream.js

const fs = require("fs");

const readStream = fs.createReadStream("./readme3.txt", { highWaterMark: 16 });
const data = [];

readStream.on("data", (chunk) => {
  data.push(chunk);
  console.log("data :", chunk, chunk.length);
  // data : <Buffer 49 20 61 6d 20 74 72 61 6e 73 66 65 72 72 69 6e> 16
  // data : <Buffer 67 20 69 6e 20 62 79 74 65 73 20 62 79 20 62 79> 16
  // data : <Buffer 74 65 73 20 63 61 6c 6c 65 64 20 63 68 75 6e 6b> 16
});

readStream.on("end", () => {
  console.log("end :", Buffer.concat(data).toString());
  // end : I am transferring in bytes by bytes called chunk
});

readStream.on("error", (err) => {
  console.log("error :", err);
});
  • createReadStream() methods takes 2 parameters

  • In the first parameter, we specify the file path

  • The second parameter is an optional and highWaterMark option helps determining the size of buffers (By default, 64KB but in this case, 16 bytes)

  • readStream is used using event listeners such as **data , end , error **events

image

  • Since file size is 48 bytes and we set data transferring capacity to 16 bytes (**highWaterMark **option), we can see that it completes the transmitting of the data in 3 times

Conclusion

Stream has following benefits over Buffer

  • continuous chunking of data ( it can arguably transmit any number of large files given infinite time) whereas Buffer has limitations in transferring large data

  • no need to wait for the entire resource to load whereas Buffer needs to do buffering (waiting)

Thank you

Enjoyed this article?

Share it with your network to help others discover it

Continue Learning

Discover more articles on similar topics