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: 4156964
Votes 0
Synopsis Using ZipEntry's InputStream to read more than 8K bytes will return error.
Category java:jar
Reported Against kestrel , 1.2beta4
Release Fixed
State 11-Closed, Not a Defect, bug
Priority: 3-Medium
Related Bugs 4269908
Submit Date 14-JUL-1998
Description
JDK: 1.2beta4-K
Locale: all
OS: solaris2.6

When using ZipEntry's InputStream to read more than 8K bytes will return error
bytes. Following is a test program to reproduce it. Please copy rt.jar file to
your runtime directory.

==========================TestZipInputStream.java========================
import java.io.*;
import java.util.zip.*;

public class TestZipInputStream {    
    public static void main(String args[]) {
	getClassFromJar("java/awt/Component.class", "rt.jar");
    }
    
    public static void readRemainder(InputStream in, byte[] bytes) throws Exception {
	int len = in.available();
	if (len > bytes.length) len = bytes.length;
	for (int i = 0; i < len; i++) {
	    bytes[i] = (byte)in.read();
	}
    }
    public static void getClassFromJar(String className, String jarName) {
	ZipFile zf;
	byte[] bytes1 = null;	
	byte[] bytes2 = null;
	try{
	    zf = new ZipFile(jarName);
	    ZipEntry ze;
	    ze = zf.getEntry(className);
	    if (ze == null) return;
	    InputStream istream = zf.getInputStream(ze);
	    bytes1 = new byte[istream.available()];
	    bytes2 = new byte[istream.available()];
	    istream.read(bytes1);
	    istream.close();
	    
	    istream = zf.getInputStream(ze);	    
	    readRemainder(istream, bytes2);
	    istream.close();
	    zf.close();
           
	    int count = 0;
	    for (int i = 0; i < bytes1.length; i ++) {
		String tmp1 = "00"+Integer.toHexString(bytes1[i]);
		String tmp2 = "00"+Integer.toHexString(bytes2[i]);
		if (!tmp1.equals(tmp2)) {
		    System.out.println("Found a mismatch error: ");
		    System.out.println("    Position: " + i);
		    System.out.println("    In bytes1 is " + tmp1);
		    System.out.println("    In bytes2 is " + tmp2);
		    count ++;
		    if (count >= 40) {
		       break;
		    }
		}
	    }
	} catch(Exception e){} 
    }

}
===========================================================================
save this file, also copy rt.jar file to your current dir.
javac TestZipInputStream.java
java TestZipInputStream
see the print out message.


  xxxxx@xxxxx   1998-07-14
Work Around
N/A
Evaluation
Not a bug. What was read in bytes1 array was only 8192 bytes. Although there
are 31104 bytes in the underlying stream, and the buffer is allocated to be
31104 bytes long, but the istream.read(bytes1) call returns 8192, and all the
remaining elements in bytes1 are still the initialized 0. But later on bytes2
array is being filled in 31104 bytes, that is why the comparison fails.

This is a pretty common problem in using read. According JLS,
for java.io.InputStream.read(b), " the number of bytes read is, at most,
equal to the length of b". So the user need to check on the return
value to determine how much data was actually read.


  xxxxx@xxxxx   1998-07-22

May be there should exists such an enhancement in the function of InputStream.read(byte[] bytes):
It should fill the bytes content as possible. Yes, you can allocate buffer
in InputStream.read(byte[]) as 8k size, but you can read more than once in
this method, till fill out the bytes, or return all the bytes in this stream,
and the return value is the actual size that you have read.
I think it is more oo with such function, while in current condition, this 
method give us inconvenience.

[  xxxxx@xxxxx   1998-07-24]
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang