38

Please, no lectures about how I should be doing everything asynchronously. Sometimes I want to do things the easy obvious way, so I can move on to other work.

For some reason, the following code doesn't work. It matches code I found on a recent SO question. Did node change or break something?

var fs = require('fs');
var rs = fs.createReadStream('myfilename');  // for example
                                             // but I might also want to read from
                                             // stdio, an HTTP request, etc...
var buffer = rs.read();     // simple for SCCCE example, normally you'd repeat in a loop...
console.log(buffer.toString());

After the read, the buffer is null.

Looking at rs in the debugger, I see

events  
   has end and open functions, nothing else
_readableState
  buffer = Array[0]
  emittedReadable = false
  flowing = false   <<< this appears to be correct
  lots of other false/nulls/undefined
fd = null   <<< suspicious???
readable = true
  lots of other false/nulls/undefined
Community
  • 1
  • 1
user949300
  • 15,364
  • 7
  • 35
  • 66
  • use readFileSync http://nodejs.org/api/fs.html#fs_fs_readfilesync_filename_options – Anthony Nov 12 '13 at 00:07
  • 3
    Yes, but, I'd also like to be able to read from Streams, not just files. My bad, edited the question to clarify. – user949300 Nov 12 '13 at 00:36
  • @user949300 `buffer` is `null` because there is no data available to read from the stream yet. You need to listen to the `readdable` event then call `rs.read()` – Bulkan Nov 12 '13 at 01:27
  • 2
    @Bulkan but calling `readableStream.on('readable', callback)` is asynchronous. I was hoping to avoid that. – user949300 Nov 12 '13 at 02:25
  • 1
    @user949300 streams are inherently asynchronous. There is no way to use them in a synchronous manner. – Bulkan Nov 12 '13 at 02:40
  • It is possible Bulkan, see my solution here: http://stackoverflow.com/questions/16010915/parsing-huge-logfiles-in-node-js-read-in-line-by-line/23695940#23695940 – Gerard May 16 '14 at 13:26

1 Answers1

10

To read the contents of a file synchronously use fs.readFileSync

var fs = require('fs');
var content = fs.readFileSync('myfilename');
console.log(content);

fs.createReadStream creates a ReadStream.

Bulkan
  • 2,555
  • 1
  • 20
  • 31
  • 21
    Yes, but, I'd also like to be able to read from Streams, not just files. My bad, edited the question to clarify. – user949300 Nov 12 '13 at 00:36
  • @user949300 [fs.readSync](http://nodejs.org/api/fs.html#fs_fs_readsync_fd_buffer_offset_length_position) might help in that case. – Bulkan Nov 12 '13 at 00:39
  • I think that would work with stdin, via process.stdin.fd, but not sure how that helps wit a stream, say, from an HTTP file upload. – user949300 Nov 12 '13 at 01:12
  • @user949300 did you get an answer for reading a stream into a string synchronously? – Darth.Vader Jun 16 '15 at 22:00
  • 2
    @Shubham. No. I reworked the code for asynch, but still seems like reading a stream sync (e.g. at startup) would be useful – user949300 Jun 16 '15 at 22:45