Issue
I learned two ways of downloading files in node js and express, but I couldn’t find out what the difference between them is: res.download(path)
and createReadStream(path)
.
I know that createReadStream()
is creating a stream to know overflow the server and it’s good way, but what about the other one?
These are the two examples:
const orderId = req.params.orderId;
const invoiceName = 'invoice-' + orderId + '.pdf';
const invoicePath = path.join('data', 'invoices', invoiceName)
res.download(invoicePath, (err) => {
if (err) {
return next(err);
}
});
and
const readStream = fs.createReadStream(invoicePath);
res.setHeader('Content-type', 'application/pdf');
res.setHeader('Content-Dispoition', 'attachment; filename=' + invoiceName);
readStream
.on('open', function () {
// This just pipes the read stream to the response object (which goes to the client)
readStream.pipe(res);
})
.on('end', function () {
readStream.unpipe(res);
console.log('All the data in the file has been read');
})
.on('close', function (err) {
console.log('Stream has been Closed');
next(err)
});
Solution
Briefly looking at express res.download() source code, it essentially automates what you are doing manually with the alternative example. This includes relying on streams for efficient transfer and minimizing memory footprint.
https://github.com/expressjs/express/blob/master/lib/response.js
It actually ends up calling the sendfile() function defined at line 1016 – which ends up calling file.pipe(res).