JDK-6294974 : FileInputStream.skip(long) does not stop at EOF
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 5.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2005-07-08
  • Updated: 2013-05-09
  • Resolved: 2013-05-09
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05)
Java HotSpot(TM) Client VM (build 1.5.0_04-b05, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
This is a duplication of 4454092 bug.

When the skip(long) method is used from any position in the stream with a skip
value that is larger than the available bytes in the stream, the skip method
skips beyond EOF and returns the same value that was given to it.
See code below.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run following program

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
JVM: Sun Microsystems Inc. 1.5.0_04
Skiped bytes: 1501
ACTUAL -
JVM: Sun Microsystems Inc. 1.5.0_04
Skiped bytes: 100000000

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.io.InputStream;

public
class SkipTest
{
	
	public static
	void	main(String[] args)
			throws IOException
	{
		InputStream is=SkipTest.class.getResourceAsStream("SkipTest.class");
		long stream_size=is.skip(100000000);
		System.out.println("JVM: "+System.getProperty("java.vendor")+" "+System.getProperty("java.version"));
		System.out.println("Skiped bytes: "+stream_size);
	}

}

---------- END SOURCE ----------
###@###.### 2005-07-08 13:07:58 GMT

Comments
The reported is a long standing behaviour of FileInputStream.skip method, which cannot be changed due to the compatibility concern. Its java spec will be updated in JDK-8011136.
09-05-2013

EVALUATION After spending some more time on this bug, I hold on to my previous evaluation that says the behavior of FileInputStream.skip(long n) is already specified. The FileInputStream.skip(long n) may skip more bytes that may include bytes beyond EOF. This behavior comes directly from the native method: lseek The solaris man page for lseek says: "The lseek() function allows the file pointer to be set beyond the existing data in the file" If the specified bytes to be skipped is 100000000, the skip() method actually skips these many bytes and returns 100000000. Things change a little when BufferedInputStream wraps a FileInputStream inside. When the buffer is marked with mark() method, the BufferedInputStream buffers (reads the data into an internal buffer) the available data that is being skipped. Hence only the data that is available to be read is skipped in this case. That's the reason when the buffer is marked, only the available data is skipped and the skip method doesn't go beyond the EOF. This is the reason the FileInputStream spec says: "This method *may* skip more bytes than are remaining in the backing file"
13-03-2006

EVALUATION I attach here a test, it shows that only change to the spec is not enough. The test creates an object of the class java.io.FileInputStream, the test repeats calling skip method to skip 100000000 and the method always returns the same value 100000000, even no more bytes to skip, and then calling the method "available" will return a value which is 100000000 less than last call to the method "available". The shows that the method available returns -499996739. If the method mark is called, then everything seems ok. If testing on different subclass of the class IOInputStream, the results are different.
05-10-2005

EVALUATION The spec has been changed in 1.5.0 to include: "This method may skip more bytes than are remaining in the backing file. This produces no exception and the number of bytes skipped may include some number of bytes that were beyond the EOF of the backing file. Attempting to read from the stream after skipping past the end will result in -1 indicating the end of the file." This bug can be closed as a duplicate of 4454092. ###@###.### 2005-07-11 08:26:26 GMT
11-07-2005