Skip to main content

A bug of java.io.BufferedInputStream.skip(long n).

5 replies [Last post]
theface
Offline
Joined: 2005-09-18

The follwing code from java.io.BufferedInputStream,:
public synchronized long skip(long n) throws IOException {
getBufIfOpen(); // Check for closed stream
if (n <= 0) {
return 0;
}
long avail = count - pos;

if (avail <= 0) {
// If no mark position set then don't keep in buffer
if (markpos <0)
return getInIfOpen().skip(n);

// Fill in buffer to save bytes for reset
fill();
avail = count - pos;
if (avail <= 0)
return 0;
}

long skipped = (avail < n) ? avail : n;
pos += skipped;
return skipped;
}

The bug will show(in my app) when:
count=8192,this is default buffer size;
pos=8191,the bytes current readed.
now skip some bytes(>1),call method skip(long n),e.g:skip(2),but in actually,it just skip 1 byte.Because:
the parameter n of method = 2;
long avail = 8192 - 8191;//avail=1
long skipped = (avail < n) ? avail : n;//(1 < 2) ? 1 : 2,skipped =1
pos += skipped;//pos+=1 ,pos=8192.
return skipped;//actually skipped is just 1 byte.

now, the current buffer is ended,the next buffer(size=8192) is readed,the read method get data bytes from the first index of buffer.so this implements is incorrect.

my java version:
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b108)
Java HotSpot(TM) Client VM (build 19.0-b05, mixed mode)

sorry for my broken english.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
theface
Offline
Joined: 2005-09-18

Dose anyone can confirm this is a bug?or the code logic of I analyzed is wrong?

I suggest a easy implement:

1)rename the old skip method to skip0:
private final long skip0(long n) throws IOException {

2)create a new skip method use code:

public synchronized long skip(long n) throws IOException {
long realSkipped = 0;
do{
int skipped = skip0(n);
realSkipped+=skipped;
if(skipped==n) break;
n = n-skipped;//
}while(true);
return realSkipped;
}

walterln
Offline
Joined: 2007-04-17

Not a bug, the javadoc says "returns the actual number of bytes skipped.", so if you want to skip more you'll just have to loop until the total skipped is the amount you want - same as with read.

theface
Offline
Joined: 2005-09-18

Oh.I don't agree,

If the user want to skip some bytes,the KPI just skip it,except End Of File.I think the returned actual number of bytes skipped should always equipment the giving parameter n,except end of file,not end the current cached buffer.

Another example,java.io.BufferedInputStream.read(byte[] b, int off, int len),as the method said, it return a number to means bytes read, or -1 if the end of the stream has been reached.in this implement,if end of the current cache buffer,it will read next cache buffer in for loop until readed length equipment giving len or EOF.

If use above logic,this read method should just read bytes from current cached buffer.do you think this is a good implement for developer?

peter__lawrey
Offline
Joined: 2005-11-01

The read() method is only guarenteed to provide 1 byte minimum, or EOF. BufferedInputStream is designed to minimise the number of reads to the underlying stream. If thats not what you want, I suggest you don't use it.

theface
Offline
Joined: 2005-09-18

As you said,the design is from core developers of JDK,you just accepted it,

I really don't know the application developers who wants to skip 2 bytes,but at first method call it just skipped 1 byte ,and must be call skip again or any more. if anyone use this method is want to skip the giving number bytes,but they must write a for loop to do this by them self,why don't use it as default implement in top level.

Anyway,In my app,I extend BufferedInputStream and overwrite the skip method to solve this problem.I just want to giving some suggest.

Sorry for my broken english,I have no more words to talk about this.:)