Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4100022
Votes 1
Synopsis java.io.BufferedInputStream.read(byte[]) method confusing to use
Category java:classes_io
Reported Against 1.1.5 , 1.2beta3
Release Fixed
State 11-Closed, duplicate of 4090383, bug
Priority: 4-Low
Related Bugs 4090383
Submit Date 17-DEC-1997
Description




today, after encountering some strange bugs 
(OutOfMemoryErrors to be precise)
while loading files using a DataInputStream,
I dug around in the java.io source files
looking for answers. 

When using the read(byte[]) call in 
DataInputStream, despite the data existing 
just fine on disk, loading a file would crash 
my app.  This occurred when using a 
DataInputStream on top of a BufferedInputStream 
on top of a FileInputStream.  When using a 
DataInputStream on top of just a FileInputStream,
I had no problems, however.

The reason for this difference was the 
read(byte[],int,int) routine in BufferedInputStream.
This routine, for some unknown reason, decides
that it is better to give up and return whatever
is available in the buffer (when the number of bytes
requested is greater than the number of bytes
remaining in the buffer) instead of re-filling
the buffer and returning a complete result.

The FileInputStream does it's best to return a
full result, but the BufferedInputStream doesn't...
why??

I realize that using the readFully(byte[]) routine
in DataInputStream is an attempt to solve this
problem, but it seems instinctive to me that
a read(byte[]) call (for any
InputStream) will do it's best to fulfill
the request unless an IO error occurs.

It seems that the readFully(byte[]) method in 
DataInputStream is just a hack to solve
a problem with the stream that DataInputStream
depends on.

This problem is explicitly visible in the 
BufferedInputStream but is it visible elsewhere??
It seems that the current read(byte[],int,int)
code in BufferedInputStream is simply lazy and
this design isn't particularly necessary.

Why can't the method try it's best to return as
much data as possible?? it could save all the
available data in buffer, refill the buffer, and
then fully complete the request before returning.
is this too much to ask?? or was there some other
reason for designing this method like this??

i suspect that most programmers will expect a
read() call to return as much data as possible
(unless there is an IO error), so i do hope
there is some  customer  reason (laziness is not a 
 customer  reason) for straying from this way of thinking.

we were baffled for a while why these 
OutOfMemoryErrors were occurring, but after
digging around in the java source code
we found out about this read(byte[]) problem(?)
in the DataInputStream (which is really more
of a problem in the BufferedInputStream)

I'm not sure if other people have had this
sort of difficulty, but I hope you do consider
re-implementing the read(byte[],int,int) routine
in BufferedInputStream so that other people
don't have to waste this much time 
(digging around in basic java source code)
to solve such a simple problem.
(Review ID: 22067)
======================================================================
Work Around




see body of bug report
(use readFully(byte[]) instead of read(byte[]))
======================================================================
Evaluation
This suggestion was implemented in JDK 1.2.  --   xxxxx@xxxxx   1998/11/16
Comments
  
  Include a link with my name & email   

Submitted On 06-MAR-1998
StH
  /** Workaround for an unexpected behaviour of 'BufferedInputStream'! */
  private static int read(byte[] buffer, int bufPos, int length) 
      throws IOException {
    int i = inFile.read(buffer, bufPos, length);
    if ((i == length) || (i == -1)) return i;
    int j = inFile.read(buffer, bufPos + i, length - i);
    if (j == -1) return i;
    return j + i;
  }


Submitted On 11-MAY-1998
hbarbieri
I think the behaviour of a "black box" function
like that:
   class X {
     public static void func(InputStream in);
   }
  should not be changed when I create a second function like that:
 class Y {
    public static void func2(InputStream in) {
       BufferedInputStream bis = new 
           BufferedInputStream (in);
       
       X.func(bis);
    }
}
  In this case I don't have the function "func" code and I can't use
readFully(Byte[]).



PLEASE NOTE: JDK6 is formerly known as Project Mustang