views:

667

answers:

7

I want to open a ZIP-file, that have no entries with java.util.zip.ZipFile. But on the constructor I get the following exception: 'java.util.zip.ZipException: error in opening zip file'. How can I open the empty ZIP?

That ZIP-file is created by the commandline zip-program under linux. I simply deleted all entries from a ZIP-file.

I need this as testdata for a class I write. The class should simply return an empty list for this case, but broken ZIP-files should return an error.

For some more explanation on the problem. I have an interface, for extracting some documents from different sources. Other implementations gather them from webservices or directories, this implementation from ZIP-files. The interface give an Iterator with some more functionality. So I want to decide, if the ZIP-file is empty or broken.

+1  A: 

I don't know why is it implemented this way, but why do you need to succesfully open an empty Zip file? You can't modify it with java.util.zip.ZipFile anyway...

So you can just catch the ZipException (which is thrown for invalid format zip files), and skip the file if you catch it.

Max
In my usecase I don't know in before, that the file will be empty. The class I write should work correct in this case also.
Mnementh
Then just catch that exception:http://java.pastebin.com/m3a8c5248
Max
How should I decide, if it is an empty ZIP-file or a broken ZIP-File? And I get no ZipFile-object, to work with.
Mnementh
Are you sure you need to know if it is bad or empty? In both cases it is useless for your program. So you basically should not need any object for an useless file. If I'm wrong, then you should explain your goal, maybe we could find some better solution.
Max
A: 

Are you sure it is a valid zip file? That would be my first guess.

recursive
A: 

The ZIP file format has errors check the JDK here.

yrcjaya
A: 

Use a ZipOutputStream.

Tom Hawtin - tackline
I try with a ZipInputStream, thanks for the hint.
Mnementh
+3  A: 

hack: you can assume that all empty ZIPs are the same and just hardcode it's length/chechsum to validate against.

Yoni Roit
That's really a hack, but it could actually work. At least worth an upvote, thanks. :-)
Mnementh
+1  A: 

My solution for this problem is now, that I simply use ZipInputStream instead of ZipFile. This class works well with empty ZIP-files. I don't know about the reason, why one works and the other not.

Mnementh
A: 

I think the reason ZipInputStream works and ZipFile does not is because of the two different ways that zip files are read. The ZipFile constructor attempts to read the ZipFile's table of contents, which is written to the end of the file. If it can't read the TOC, it throws a ZipException (with almost no helpful info contained therein), which I think is what you're seeing. ZipInputStream, however, reads the entries out of the zip file sequentially starting at the beginning of the file, so it seems more robust in this case.

This is all very poorly documented and I've run into similar problems myself using ZipFile. Both methods of reading from a zip file are valid, but you'd think the API docs would mention the implications of the random access/TOC method of reading through constructor versus reading through a ZipInputStream.

Jeff