nodejs - fs.createReadStream().pipe, how to know size of file issue

16,567

Solution 1

Well you should only send the response and pipe the file after you get the size with fs.stat, like so:

fs.stat(file_path, function(error, stat) {
  if (error) { throw error; }
  response.writeHead(200, {
    'Content-Type' : 'image/gif',
    'Content-Length' : stat.size
  });
  // do your piping here
}); 

Solution 2

There is also a synchronous version (since you'll be blocking on file I/O anyway...) as mentioned in this other post

var stat = fs.statSync(pathOfFile);
response.writeHead(200, {
    'Content-Type' : 'image/jpeg',
    'Content-Length' : stat.size
});
// pipe contents
Share:
16,567
user1066986
Author by

user1066986

Updated on June 25, 2022

Comments

  • user1066986
    user1066986 almost 2 years

    I am writing my own HTTP module, if I need to response with a binary file, e.g. .jpg,

    I load the file using: body = fs.createReadStream(pathOfFile).

    When I generate the response I use:body.pipe(socket);

    But as its HTTP response, I had like to add a Content-Length header.

    I couldn't find an easy way to do it, fs.stat doesn't give the result immediately but just after I called pipe.

    Anyway to know what to send in Content-Length header. ?

    Thanks.

  • XMB5
    XMB5 over 5 years
    This introduces a race condition - the file might change between the stat and the piping
  • Jamie Pate
    Jamie Pate almost 2 years
    You definitely don't want to do this when writing a web server or any other multi-request system... the whole point of fs.stat() is that it's NON-BLOCKING. If you are writing a web server and you use stat instead of statSync then your single threaded nodejs process can continue serving other requests while the file I/O happens...