[Fixed] The difference between res.download() and createReadStream() in downloading files

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).

Leave a Reply

(*) Required, Your email will not be published