13

私はzipファイルを抽出するための簡単なコードを持っています。それは期待通りにうまく機能していましたが、テスト中に、zipファイルを抽出する必要があることを確認するために、いくつかのzipファイル(インターネットからダウンロードしたフォント、アイコン、およびテンプレート)でコードを試しました提供されていますが、一部の zip ファイルでは機能しません。この問題を再現するための最小化されたコードを次に示します。

package com.test.mytest;

import java.io.FileInputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

public class ZipExtractTest {

    public static final String ZIP_FILE = "/Users/XXXXX/Downloads/janne.zip";

    public static void main(String[]args) {
        unzipFile(ZIP_FILE);
        unzipStream(ZIP_FILE);
    }

    public static void unzipFile(String zipName) {
        try {

            ZipFile zf = new ZipFile(zipName);

            Enumeration ent = zf.entries();

            while(ent.hasMoreElements()) {
                System.out.println(ent.nextElement());
            }

        } catch(Exception e) {
            System.out.println(e);
        }
    }

    public static void unzipStream(String zipName) {
        try {
            ZipInputStream zis = new ZipInputStream(new FileInputStream(zipName));
            ZipEntry ze = zis.getNextEntry();

            if(ze == null) {
                System.out.println("unable to get first entry from zip file");
                zis.close();
                return;
            }

            while(ze != null) {
                System.out.println("Entry Found: " + ze);
                ze = zis.getNextEntry();
            }

            zis.closeEntry();
            zis.close();

        } catch(Exception e) {
            System.out.println(e);
        }
    }
}

実際、実際のアプリケーションでは、入力ストリームを介して zip ファイルを抽出する必要があります。上記のコードでは、「janne.zip」を抽出しようとしていますhttp://www.iconian.com/fonts/janne.zipからこのファイルをダウンロードしました。任意の zip ツールを使用して、驚くべきことに「unzipFile」を使用して抽出できます。 (String zipName)" メソッドも同様ですが、unzipStream(String zipName) メソッドを使用します。

ZipEntry ze = zis.getNextEntry();

null を返します

任意の助けをいただければ幸いです

4

3 に答える 3

21

この特定のファイルが で動作しない理由についての答えではありませんが、 の使用をApache commons-compress (API 互換である必要があります)java.util.zipに置き換えるオプションがある場合は、例でそれをテストしましたファイルであり、正常に動作しているようです。java.util.zip.ZipInputStream org.apache.commons.compress.archivers.zip.ZipArchiveInputStream

一般に、commons-compress は、クラス自体java.util.zip以外のツールによって作成されたファイルを解凍する場合よりもはるかに信頼性が高いと思います。java.util.zip

編集: Eclipse で少しデバッグを行ったところ、この特定の zip ファイルには、最初のエントリのローカル ヘッダーのLOC 署名 () の前に単一のセグメント スパン マーカーがあるようです。これは、commons-compressが処理方法を知っているが、知らないものです。LOC 署名以外のものを見た場合は、が返されます。0x30304b500x04034b50java.util.zipj.u.z.ZipInputStreamgetNextEntry()null

于 2013-03-20T11:48:40.737 に答える
5

面白い!

コードをデバッグしましたが、同じエラーが発生しました。ZipInputStream実装でヘッダーチェックが見つかりましたが、ZipFile実装では見つかりませんでした。

理由を聞かないでください。ただし、zipファイルのヘッダーは無効です

Your file is starting with: 50 4B 30 30 50 4B 03 04
A valid Zip File Header is: 50 4B 03 04

ファイルから最初のバイト(50 4B 30 30)を削除すると、有効なヘッダーが取得され、ファイルを読み取ることができます。

于 2013-03-20T13:06:34.137 に答える