Reading Files into memory in NodeJs




reading file data into memory to serve it as a response is not really a good practice, for tiny files it might be ok but for bigger files, it certainly is not, instead you should be streaming your response data and that is what I will do now.


First of all How to read files into Memory

exports.getInvoice = (req, res, next) => { const orderId = req.params.orderId; Order.findById(orderId) .then(order => { if (!order) { return next(new Error('No order Found.')); } if (order.user.userId.toString() !== req.user._id.toString()) { return next(new Error('Unauthorized User.')); } const invoiceName = 'invoice-' + orderId + '.pdf'; const invoicePath = path.join('data', 'invoices', invoiceName); fs.readFile(invoicePath, (err, data) => { if (err) { return next(err); } res.setHeader('Content-Type', 'application/pdf') res.setHeader('Content-Disposition', 'inline; filename="' + invoiceName + '"') res.send(data); }) }) .catch(err => { return next(err); }) }; Now the streaming file comes in

const file = fs.createReadStream(invoicePath);

I will use that file read stream and call the pipe method to forward the data that is read in with that stream to my response because the response object is a writable stream actually


We can pipe our readable stram , the file stream into response and that means that the response will be streamed to the browser and will contain the data and the data will basically be downloaded by the browser step by step and for large files, this is a huge advantage because node never has to pre-load all the data into memory but just streams it to the client on the fly and the most it has to store is one chunk of data.

Again we are back to the buffer and streams, the chunks are what we work with, the buffers

basically gives us access to these chunks and here we don't wait for all the chunks to come together and concatenate them into one object, instead we forward them to the browser which then is also able to concatenate the incoming data pieces into the final file.


So now this streamed data created with that create read stream thing which is the recommended way of getting your

const invoiceName = 'invoice-' + orderId + '.pdf'; const invoicePath = path.join('data', 'invoices', invoiceName); const file = fs.createReadStream(invoicePath); res.setHeader('Content-Type', 'application/pdf') res.setHeader('Content-Disposition', 'inline; filename="' + invoiceName + '"'); file.pipe(res); }) .catch(err => { return next(err); }) };

0 views0 comments

Recent Posts

See All

SQL UNION Operator UNION operator is used to combine the results of two or more SELECT statements Every SELECT statement within UNION must have the same number of columns The columns must also have si

JOIN clause is used to combine rows from two or more tables. INNER JOIN === selects records that have matching values in both tables SELECT Orders.OrderID, Customers.CustomersID, Orders.OrdersDate FRO