United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4254082 : java.io.BufferedInputStream.skip has unexpected results

Details
Type:
Enhancement
Submit Date:
1999-07-14
Status:
Closed
Updated Date:
2002-05-09
Project Name:
JDK
Resolved Date:
2002-05-09
Component:
core-libs
OS:
windows_nt,generic
Sub-Component:
java.io
CPU:
x86,generic
Priority:
P4
Resolution:
Won't Fix
Affected Versions:
1.2.0,1.2.2
Fixed Versions:

Related Reports

Sub Tasks

Description

Name: rlT66838			Date: 07/14/99


In JDK 1.2 the method skip(long n) leads to unexpected results when
using with BufferedInputStreams. The number of skipped values
is often smaller than desired, without any good reasons
(for example the end of the byte stream). Nevertheless the return
value of skip() gives the correct (lower) skip number.

The problem is not occuring with JDK 1.1 or when using
 
        FileInputStream inp = new FileInputStream(fileName);

instead of

        BufferedInputStream inp = new BufferedInputStream(
                new FileInputStream(fileName), bufferSize);

In the following I included a small java program whichs
demonstrates the problem.

import java.lang.*;
import java.io.*;
import java.util.*;

public class CheckSkipInBufferedInputStream {
  public static void main(String args[]) {
    byte[] byteArray = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
    int bufferSize, i, b;
    try {
       bufferSize = Integer.parseInt(args[0]);
    }
    catch (Exception e) {
       bufferSize = 8;
    }   
    try {
       BufferedInputStream inp = new BufferedInputStream(
           new ByteArrayInputStream(byteArray), bufferSize);
//       ByteArrayInputStream inp = new ByteArrayInputStream(byteArray);
       
       for (i=0;i<=4;++i) {
          b = inp.read();
          System.out.println(" byteArray["+i+"]="
                       +byteArray[i]+" read(): "+b);
       }
       i = (int)inp.skip(5l);
       System.out.println(i+" values skipped");
// work around:
//       for (i=1;i<=5;++i)
//          inp.skip(1);
       for (i=5;i<=9;++i) {
          System.out.println(" byteArray["+i+"]="
                        +byteArray[i]+" skipped");
       }
       for (i=10;i<byteArray.length;++i) {
          b = inp.read();
          System.out.println(" byteArray["+i+"]="
                       +byteArray[i]+" read(): "+b);
       }
       inp.close();
    }
    catch (Exception e) {
       e.printStackTrace();
    }
  }   
}

In a byte array of length 20 the program tries to skip 5 values
at position 5. Look at the program output using JDK 1.2:

 byteArray[0]=0 read(): 0
 byteArray[1]=1 read(): 1
 byteArray[2]=2 read(): 2
 byteArray[3]=3 read(): 3
 byteArray[4]=4 read(): 4
3 values skipped
 byteArray[5]=5 skipped
 byteArray[6]=6 skipped
 byteArray[7]=7 skipped
 byteArray[8]=8 skipped
 byteArray[9]=9 skipped
 byteArray[10]=10 read(): 8
 byteArray[11]=11 read(): 9
 byteArray[12]=12 read(): 10
 byteArray[13]=13 read(): 11
 byteArray[14]=14 read(): 12
 byteArray[15]=15 read(): 13
 byteArray[16]=16 read(): 14
 byteArray[17]=17 read(): 15
 byteArray[18]=18 read(): 16
 byteArray[19]=19 read(): 17

Without any good reason only 3 values are skipped. Executing the
program with JDK 1.1 everything works as expected. With JDK 1.2
using ByteArrayInputStream without BufferedInputStream
also 5 values are skipped. The program allows the buffer size 
as an argument (for demonstration purpose the default value is 8).
Increasing the buffer size to 10 or higher eliminates the problem
too. The problem seems to arise when the internal buffer 
has to be refreshed while skipping.

To work around the problem just repeat a skip of value 1.
(Review ID: 85567) 
======================================================================

                                    

Comments
EVALUATION

This is not in violation of spec but it might be an improvement to skip over buffer boundaries like people would expect. I'm changing this to an rfe.
michael.mccloskey@eng 1999-07-26
                                     
1999-07-26
WORK AROUND



Name: rlT66838			Date: 07/14/99


Use
   for (i=1;i<=skiplength;i++)
      inp.skip(1);
instead of 
   skip(skiplength);
and always check the return value;
======================================================================
                                     
2004-06-11



Hardware and Software, Engineered to Work Together