11

I was always wondering: What is the end of a stream?

In the javadoc of most readLine methods in the java.io package, you can read that "this returns null if the end of the stream is reached" - though I never actually got a null, as most streams (in the case of a network stream that I use most often) just block the program execution until something is written into the stream on the remote end

Are there ways to enforce this acutal behavior happening in an actual non-exception throwing way? I am simply curious ...

salbeira
  • 2,375
  • 5
  • 26
  • 40

3 Answers3

12

Think of a file being read. There is an end of stream there, the end of the file. If you try to read beyond that, you simply can't. If you have a network connection though, there doesn't need to be an end of stream if you simply wait for more data to be sent.

In the case of the file, we know for a fact that there is no more data to be read. In the case of a network stream we (usually) don't.

Blocking a FileReader when no more data is available, awakening when there is: the simple answer is: you can't. The fundamental difference is that you read a file actively, but when you listen to a network stream you read passively. When something comes from the network your hardware sends a short of signal to the Operating System, which then gives the new data to your JVM, and the JVM then awakens your process to read the new data (so to speak). But we don't have that with a file, at least not immediately.

A possible workaround would be to make a wrapper to the StreamReader you have, with a listener that is notified when the file is changed, which then awakens you to read further. In Java 7 you can use the WatchService.

Julián Urbano
  • 8,378
  • 1
  • 30
  • 52
  • I actually managed to get the reader to return null by closing the socket on the remote end - obviously the stream is terminated, but also an indicator is being set to tell anything trying to read from it that it has literally ended (to receive data) ... This is the moment I have waited for to insert cleanup code when the remote end closes the connection! – salbeira Dec 18 '13 at 03:07
  • 1
    You can check [`configureBlocking`](http://docs.oracle.com/javase/7/docs/api/java/nio/channels/spi/AbstractSelectableChannel.html#configureBlocking(boolean)) and [`available`](http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#available()) – Julián Urbano Dec 18 '13 at 03:12
3

At some point, the socket will be closed, and no more data can be sent via that stream. This is when the InputStream will signal EOF by returning -1 from read() and its overloads. This state is irreversible. That stream is dead.

Simply blocking for more data on an open stream is not an EOF condition.

erickson
  • 265,237
  • 58
  • 395
  • 493
  • What is the exact difference between EOF and EOS(tream)? - An answer like "the character-code" is also valid – salbeira Dec 18 '13 at 02:39
  • @salbeira There is no difference, and no data is actually transmitted over the stream (or read from the file). This result is generated by the `InputStream` implementation class. It's the result of logic, it's not an in-band signal. – erickson Dec 18 '13 at 02:54
2

I never actually got a null, as most streams (in the case of a network stream that I use most often) just block the program execution until something is written into the stream on the remote end

No. You never got a null because the peer never closed the connection. That's what 'end of stream' means. It doesn't mean 'no more data for the time being'.

user207421
  • 305,947
  • 44
  • 307
  • 483