• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Junilu Lacar
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Rob Spoor
  • Bear Bibeault
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Piet Souris
  • Carey Brown
  • Stephan van Hulst
Bartenders:
  • Frits Walraven
  • fred rosenberger
  • salvin francis

Why does a BufferedInputStream go to -1 during a read?

 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why is there a check to see if Java is -1, why not a multiple like -10, or -33?  Secondly, I believe this is to check if the data read is out of bounds (it should get to -1 at the end of the buffer read if I recall).
I have seen an explanation before, I am unable to find it at the moment. Any hints are appreciated.



Source: http://tutorials.jenkov.com/java-exception-handling/try-with-resources.html
 
Rancher
Posts: 4801
50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The explanation is in the API docs for BufferedReader.read.

Returns
The character read, as an integer in the range 0 to 65535 (0x00-0xffff), or -1 if the end of the stream has been reached
 
Saloon Keeper
Posts: 23883
162
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is an example of a heterogeneous result set.

The read method can return a result that's 1 of 2 types:

1. 0 or more characters/bytes/records (depending on what's doing the reading)

or

2. "No more data to read"

If this method had been invented in the Java era, "no more data" would probably be an exception, but this is one of the functionalities carried over from C. C did not support throwing any sort of exception - that didn't arrive until about 20 years later, when Bjarne Stroustrup invented C++. So the alternative was to return a value that was patently impossible, but still managed to fit within the type constraints of the method's return type.

Actually, in C, errors were also possible, and they, too had negative values. But that was Too Much of a Good Thing for Java, so Java instead handles actual errors by throwing Exceptions.
 
Sheriff
Posts: 22258
119
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:If this method had been invented in the Java era, "no more data" would probably be an exception


I partly disagree. Yes, there should probably be an exception if a read is attempted when no more data is available (there is in fact class java.io.EOFException). However, there should also be a way of detecting EOF in the first place, otherwise you would have to use the EOFException as the "stop reading" signal. That could be done by adding a method eof() or something like that that can return when EOF is reached. This would then lead to this:

Some notes:
* It's now possible to declare the variables required for reading inside the method body. For performance reasons the byte[] should probably still be declared outside though.
* A single byte read can return a byte because there is no more need for 257 values (-1 plus 0-255).
* A multiple byte read still needs to return the number of bytes read, because eof() only tells you that the end of the stream hasn't been reached yet, but not how many are available. (Method available() still shouldn't be used, because this information may simply be unknown.)
 
Tim Holloway
Saloon Keeper
Posts: 23883
162
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think there's a couple of reasons why things weren't done that way.

First, because we're coming from a C/minicomputer/geek perspective, so 2 calls *(eof test/read)" would be more memory/cpu and less clever and the original methods had to conserve resources that are cheap today. Also precedent was there from search algoriths where you also have non-homogeneous results (found at index/not-found).

Secondly, since I/O takes an extended amount of time relative to computation, you could end up with some significant issues in the interval between testing and reading. Among other things, blocking versus non-blocking functions and whether  to handle a case where eof didn't block, but the read completed with end-of-file detected at read time or alternatively adding extra delays to try and prevent such a scenario. And in certain cases, such as IBM mainframes, end-of-file is actually a hardware I/O response to a read attempt in some cases. Tape drives, for example, have an explicit data marker that has to be read to signal end-of-file. So does traditional IBM DASD (disk) storage.
 
reply
    Bookmark Topic Watch Topic
  • New Topic