Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

createReadStream().pipe() Callback

Sorry in advance, I have a couple of questions on createReadStream() here.

Basically what I'm doing is dynamically building a file and streaming it to the user using fs once it is finished. I'm using .pipe() to make sure I'm throttling correctly (stop reading if buffer's full, start again once it's not, etc.) Here's a sample of my code I have so far.

http.createServer(function(req, res) {
  var stream = fs.createReadStream('<filepath>/example.pdf', {bufferSize: 64 * 1024})

  stream.pipe(res);

}).listen(3002, function() {
  console.log('Server listening on port 3002')
})

I've read in another StackOverflow question (sorry, lost it) that if you're using the regular res.send() and res.end() that .pipe() works great, as it calls the .send and .end and adds throttling.

That works fine for most cases, except I'm wanting to remove the file once the stream is complete and not using .pipe() means I'm going to have to handle throttling myself just to get a callback.

So I'm guessing that I'll want to create my own fake "res" object that has a .send() and .end() method that does what the res usually does, however on the .end() I'll put additional code to clean up the generated file. My question is basically how would I pull that off?

Help with this would be much appreciated, thanks!

like image 865
AlbertEngelB Avatar asked Feb 19 '13 16:02

AlbertEngelB


People also ask

What is the use of createReadStream?

The createReadStream() method is an inbuilt application programming interface of fs module which allow you to open up a file/stream and read the data present in it.

Is createReadStream asynchronous?

createReadStream() is an asynchronous operation that has completion events. But, because of the way it's been combined with reading from the file, you don't generally have to use it like it's asynchronous because it's asynchronous behavior is combined with the async reading from the file.

What is the correct way to pipe a readable stream and a writable stream?

To consume a readable stream, we can use the pipe / unpipe methods, or the read / unshift / resume methods. To consume a writable stream, we can make it the destination of pipe / unpipe , or just write to it with the write method and call the end method when we're done.


1 Answers

The first part about downloading can be answered by Download file from NodeJS Server.

As for removing the file after it has all been sent, you can just add your own event handler to remove the file once everything has been sent.

var stream = fs.createReadStream('<filepath>/example.pdf', {bufferSize: 64 * 1024})
stream.pipe(res);

var had_error = false;
stream.on('error', function(err){
  had_error = true;
});
stream.on('close', function(){
  if (!had_error) fs.unlink('<filepath>/example.pdf');
});

The error handler isn't 100% needed, but then you don't delete the file if there was an error while you were trying to send it.

like image 125
loganfsmyth Avatar answered Oct 13 '22 04:10

loganfsmyth