JDK-4850305 : BufferedReader.skip(long) blocks when it could return some data
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 1.4.1
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2003-04-17
  • Updated: 2005-11-15
  • Resolved: 2005-11-15
Related Reports
Duplicate :  
Description
Name: nt126004			Date: 04/17/2003


FULL PRODUCT VERSION :
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)


FULL OS VERSION :
Linux 2.4.20
i686


A DESCRIPTION OF THE PROBLEM :
Trying to skip data from a BufferedReader does not work properly.

The following code sequence eventually blocks:

if (in.ready()) {
  System.err.println(in.skip(DEFAULT_SKIP));
}

if in.ready() indicates that the stream is ready to be read, skip should not block, even if DEFAULT_SKIP is greater than the number of available characters.
I would expect it to return the actual number of characters skipped, as indicated in the documentation. Instead, skip does not return anything but blocks.

The point is that the method correctly blocks until SOME characters are 
available. But once characters have been available, it should return the 
number of characters skipped instead of blocking again ("This method 
will block UNTIL SOME CHARACTERS ARE AVAILABLE, an I/O error occurs, or 
the end of the stream is reached.").

By the way, I had used a BufferedInputStream before. This method only 
initially blocks (i.e. until some bytes are available), and returns the 
number of bytes skipped if less characters are available than requested 
to be skipped. Thus, the behavior of the BufferedInputStream's skip 
method differs form the BufferedReader's skip mehtod, which I find very 
confusing, especially since the method description in the API 
documentation is exactly the same. Similarly, the read method also only 
initially blocks.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use the source code provided below.
Enter a number of characters when requested, which is less than 9 and press enter.
The skip method will block instead of returning the actual number of characters skipped.


EXPECTED VERSUS ACTUAL BEHAVIOR :
I would expect the skip method to return the actual number of characters skipped, as indicated in the documentation. Instead, skip does not return anything but blocks.

if in.ready() indicates that the stream is ready to be read, the skip method blocks if DEFAULT_SKIP is greater than the number of available characters.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.*;

public class BufferedReaderBug {
 public static void main(String[] args) {
  BufferedReader in
   = new BufferedReader(new InputStreamReader(System.in));
  try {
   System.out.print("Please enter some characters and press enter:");
   long read = 0;
   while (read == 0) {
    while (in.ready()) {
     System.err.println("Skipping...");
     read = in.skip(10);
     System.err.println(read);
    }
   }
  }
  catch (IOException e) {
   e.printStackTrace();
  }
 }
}

---------- END SOURCE ----------
(Review ID: 183725) 
======================================================================

Comments
EVALUATION This problem exists because BufferedReader.skip(long) calls the internal method BufferedReader.fill() which in turn calls read() on the underlying stream. The test case has the following declaration: BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); Since System.in is a BufferedInputStream this is going to call BIS.read(). That method calls BIS.fill() which will block until the entire buffer (defaultBufferSize = 8192, or explicit size provided during construction) is filled. This problem is a duplicate of bug 6192696.
15-11-2005

EVALUATION This behavior has been present since at least 1.2, therefore this is not for Mantis. ###@###.### 2003-04-18
18-04-2003