Strange behavior of ZipInputStream

I have a problem with ZipInputStream. Essentially, I receive and InputStream (that's why I cannot use ZipFile), and I need to unzip it and read all its entries. The problem is that the entries are xml files, so I need to build the dom, but when I call DocumentBuilder.parse, it reads all the input stream, and closes it. So, I've tried to read one entry at once, and parse it; but now it seems that ZipEntry.getSize() always returns a -1 length. Could someone explain me why? Also, do you know any good online resource about this? Because Ive done several searches but never found something useful. Thanks

ZipInputStream iz = new ZipInputStream( is ); // "is" is an InputStream

try

{

while( iz.available() == 1 )

{

ZipEntry entry = iz.getNextEntry();

if( entry != null )

if( entry.getSize() != -1 )

{

if( entry.getName().endsWith( "header.xml" ) )

{

long n = entry.getSize();

byte[] bytes = new byte[(int)n];

iz.read( bytes );

new ByteArrayInputStream( bytes );

XmlNode xml = new XmlNode( new ByteArrayInputStream( bytes ) ); // This calls DocumentBuilder.parse

project.setName( xml.path( "header/name" ).getValue( "Project" ) );

continue;

}

else

{

// do something

}

}

iz.close();

}

catch( IOException ioe )

{

ioe.printStackTrace();

}

[1424 byte] By [yann74a] at [2007-11-27 7:14:34]
# 1
Did you ever find a solution to this? I've had this exact problem for a month now, and I still can't figure it out.
danielzeva at 2007-7-12 19:04:50 > top of Java-index,Core,Core APIs...
# 2

ZipEntry.getSize() , and all others getters, don't work well if the Stream is not a FileStream .

You may read the Input while until get a -1 .

try some like this

int i = 0, j = 0;

while((i=iz.read(bytes, j, Math.min(256, size-j))) > 0)

j += i;

pbulgarellia at 2007-7-12 19:04:50 > top of Java-index,Core,Core APIs...
# 3
Not sure to understand the correct usage: ZipEntry.getSize() always returns -1, so how do I get the size to read?Anyway, thank you for your reply
yann74a at 2007-7-12 19:04:50 > top of Java-index,Core,Core APIs...
# 4
The InputStream of the ZipEnrtry should return -1 at the end of the entry.
ejpa at 2007-7-12 19:04:50 > top of Java-index,Core,Core APIs...
# 5

It should, but it does not; I've put the code in a stand-alone class. You can compile it and launch it by specifying a zip file on the command line. I always get: Size of TestFileN: -1

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStream;

import java.util.zip.ZipEntry;

import java.util.zip.ZipInputStream;

public class ZipTest

{

public static void main( String[] args )

{

try

{

parse( new FileInputStream( new File( args[0] ) ) );

}

catch( IndexOutOfBoundsException oe )

{

System.out.println( "No filename given" );

}

catch( FileNotFoundException e )

{

System.out.println( "File not found: " + args[0] );

}

}

public static void parse( InputStream is )

{

ZipInputStream iz = new ZipInputStream( is );

try

{

while( iz.available() == 1 )

{

ZipEntry entry = iz.getNextEntry();

if( entry != null )

{

System.out.println( "Size of " + entry.getName() + ": " + entry.getSize() );

}

}

iz.close();

}

catch( IOException ioe )

{

ioe.printStackTrace();

}

}

}

yann74a at 2007-7-12 19:04:50 > top of Java-index,Core,Core APIs...
# 6

It does not always know the length of the zip entry. You can however extract the data for a given entry by just reading from the ZipInputStream until it returns -1. Then get the next entry.

The reason it does not know the length is that the zipEntry comes before the data but since the data is written in a streaming manner it does not know in advance how large it will be. By the time it does know it has normally flushed the segement of the stream containing the zipEntry. However it does insert markers into the stream to mark the end of zip entries which allows it to return -1 when you have read the stream.

more infor and examples here

http://java.sun.com/developer/technicalArticles/Programming/compression/

matfud

matfuda at 2007-7-12 19:04:50 > top of Java-index,Core,Core APIs...
# 7
> It should, but it does not; I've put the code in a> stand-alone class.Prove it. This code is just the same old non-working available() technique. If you called read() and tested the result for -1 and it never happened you might have something, but you don't.
ejpa at 2007-7-12 19:04:50 > top of Java-index,Core,Core APIs...
# 8
> more infor and examples here> http://java.sun.com/developer/technicalArticles/Progra> mming/compression/This is what I was looking for, it explains everything. Thank you very much.
yann74a at 2007-7-12 19:04:50 > top of Java-index,Core,Core APIs...