0
Java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b26)

私はコアjava.util.zipクラスを使用しています。次のコードを使用してクライアント ファイルを解凍します。

public static InputStream unzip(String file,InputStream zip)
        throws IOException {
    file = file.toLowerCase();
    ZipInputStream zin = new ZipInputStream(new BufferedInputStream(zip));
    ZipEntry ze;
    while( (ze = zin.getNextEntry()) != null ) {
        if ( ze.getName().toLowerCase().equals(file) )
            return zin;
    }
    throw new RuntimeException(file+" not found in zip");
}

次のエラーが表示されます:

invalid entry size (expected 1355916815 but got 5650884111 bytes) 

ただし、JDK 1.6 では同じコードが正常に機能します。

私は一日中検索しましたが、Java JDK にこのコードに対応する変更があることを見つけることができませんでした。

私の調査結果を裏付ける適切な原因またはリンクを見つけるのを手伝ってください。

4

1 に答える 1

1

は、1355916815 == (int) 5650884111LZIP5650884111形式のサイズ フィールド用に予約されている 4 バイトを使用して表現できない数値です。

あなたが言ったので、ZIP64形式をサポートしていないJava 6で動作したので、実際にはバイトのファイルをサポートしていないZIPファイルがあると結論付けることができますが、5650884111その制限を単に無視したツールによって生成され、実際のサイズの下位 32 ビットのみが格納されます。

どうやら、抽出プロセスが実装されていたため、無効なファイルが偶然に機能したようです。その後、圧縮されたバイトを処理し、結果のバイト数をヘッダーに格納されている圧縮されていないサイズで検証します。抽出されたバイト数が 32 ビットint変数に格納され、抽出プロセス中に静かにオーバーフローし、最後にのみ検証される場合、格納された 32 ビット サイズと同じように見えます。

Java 6 と Java 8 の間に ZIP64 サポートが追加されたので、デコーダーはlong変数を使用するように変更されたと思いますが、これは合理的です。古い ZIP ファイルと ZIP64 ファイルの両方を処理するために同じデコーダーを使用できるからです。1355916815次に、抽出されたバイト数がオーバーフローしなくなり、格納されたサイズが実際に抽出されたバイト数と一致しないことに気付き5650884111ます。

Java 6 をサポートする必要がない限り、ファイルを有効な ZIP64 ファイルとして (再) 作成すると、問題が解決するはずです。

( Java 7 で ZIP64 サポートが追加されました)

于 2016-05-31T10:54:37.130 に答える