I have a corrupted zip file whose contents I'm trying to salvage. I know that the problem is with one of the files in the sbutman/taxes/ directory, and I've resigned myself to losing it. I've written the following short program to try to extract as much data as I can from the archive:
/*
* Created on Sep 7, 2005
*/
import java.io.*;
import java.util.zip.*;
/**
* @author sbutman
*/
public class ZipExtractor {
static final int BUFFER = 8192;
public static void main( String argv[] ) {
try {
BufferedOutputStream dest = null;
FileInputStream fis = new FileInputStream( argv[0] );
ZipInputStream zis = new ZipInputStream( new BufferedInputStream(
fis ) );
ZipEntry entry;
while( true ) {
try {
entry = zis.getNextEntry( );
if ( entry == null ) break;
if ( entry.getName( ).startsWith( "sbutman/taxes/" ) )
continue;
System.out.println( "Extracting: " + entry.getName( ) );
if ( entry.isDirectory( ) ) {
File directoryEntry = new File( entry.getName( ) );
directoryEntry.mkdir( );
}
else {
int count;
byte data[] = new byte[BUFFER];
// write the files to the disk
FileOutputStream fos = new FileOutputStream( entry
.getName( ) );
dest = new BufferedOutputStream( fos, BUFFER );
while( ( count = zis.read( data, 0, BUFFER ) ) != -1 ) {
dest.write( data, 0, count );
}
dest.flush( );
dest.close( );
}
}
catch( IOException ioe ) {
System.out.println( "An IO exception has occurred:" );
ioe.printStackTrace( );
continue;
}
}
zis.close( );
}
catch( Exception e ) {
System.out.println( "A general exception occurred:" );
e.printStackTrace( );
}
}
}
When I run the program, everything works fine until I get to the zip file entry causing the problem. The output looks like this:
An IO exception has occurred:
java.util.zip.ZipException: invalid entry size (expected 4007 but got 4055 bytes)
at java.util.zip.ZipInputStream.readEnd(ZipInputStream.java:367)
at java.util.zip.ZipInputStream.read(ZipInputStream.java:141)
at java.util.zip.ZipInputStream.closeEntry(ZipInputStream.java:91)
at java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:69)
at ZipExtractor.main(ZipExtractor.java:23)
An IO exception has occurred:
java.io.IOException: Push back buffer is full
at java.io.PushbackInputStream.unread(PushbackInputStream.java:204)
at java.util.zip.ZipInputStream.readEnd(ZipInputStream.java:348)
at java.util.zip.ZipInputStream.read(ZipInputStream.java:141)
at java.util.zip.ZipInputStream.closeEntry(ZipInputStream.java:91)
at java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:69)
at ZipExtractor.main(ZipExtractor.java:23)
An IO exception has occurred:
java.io.IOException: Push back buffer is full
at java.io.PushbackInputStream.unread(PushbackInputStream.java:204)
at java.util.zip.ZipInputStream.readEnd(ZipInputStream.java:348)
at java.util.zip.ZipInputStream.read(ZipInputStream.java:141)
at java.util.zip.ZipInputStream.closeEntry(ZipInputStream.java:91)
at java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:69)
at ZipExtractor.main(ZipExtractor.java:23)
The second error repeats itself until I ctrl-c out of the program.
What's happening is that the inner catch block detects the zip entry error as expected. It continues on the next pass through the while loop and attempts to read the next entry, whereupon the second IOException is thrown over and over again. (Incidentally, I've also tried using java.util.zip.ZipFile, but it won't even
open the file.)
My questions are these:
1. What exactly does "Push back buffer is full" mean? I've looked through the javadocs, but my understanding is still sketchy. Can I manipulate the buffer or otherwise code around the problem in order to prevent this error from being thrown?
2. Is there any way I can see the source code for java.util.zip.ZipInputStream? It would be very helpful to see exactly where and why this error is being thrown.
Any help anyone can provide would be greatly appreciated. By the way, if this question should be better posted in another forum, let me know and I'll re-post it there.