#ziplibで圧縮したZIPファイルをJavaの標準ライブラリで解凍できないことがある

題名の通り。

.NETの世界に#ziplibというライブラリがあって、これを使って圧縮したZIPファイルをJavajava.util.zipパッケージの標準ライブラリで解凍しようとすると、例えば次のようなException(ZipException)が発生することがある。

invalid entry compressed size (expected 4294967295 but got 157 bytes)

これは、#ziplibが生成するZIPファイルの中のエントリのデータ記述子に書かれている「圧縮サイズ」フィールドに-1が設定されることがあるためである(どのようなケースで-1が設定されるかについては未調査)。

ZipInputStreamは、エントリのデータを伸張した後に実際に読み取った圧縮データの長さとデータ記述子に書かれている圧縮サイズとの比較を行なっているが、-1と実際のデータ長をそのまま比較した結果値が食い違っているとしてZipExceptionをスローする。

.ZIP File Format Specificationには圧縮後のデータ長として-1を設定して良いという記述は見つからなかったので、おそらく#ziplib側の問題だと思われる。

なお、Javaの標準ライブラリでエラーになるZIPファイルは、WindowsXPのunzipコマンド(ちなみに、標準でunzipコマンドが入っていることを今日まで知らなかった…)でも解凍エラーになる。ただし、一般的なZIP圧縮解凍アプリケーションでは問題なく解凍できるものも多いようである。

.NETアプリケーションとJavaアプリケーションでZIPファイルのやりとりを行なう場合は注意されたい。