1

作業コード:

InputStream is  = zipFile.getInputStream(zipArchiveEntry);
BufferedReader br = new BufferedReader(new InputStreamReader(zis));
StringBuilder sb = new StringBuilder();

String line;
while ((line = br.readLine()) != null) {
      System.out.println(line);
} 

コードが機能しない

    InputStream is  = zipFile.getInputStream(zipArchiveEntry);

    ZipArchiveInputStream zis = new ZipArchiveInputStream(is);
    if(zis.canReadEntryData(zipArchiveEntry)) {
            // Start
        BufferedReader br = new BufferedReader(new InputStreamReader(zis));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
                System.out.println(line);
        } 
}

アイデアはInputStreamから読み取るのではなく、inputStreamからZipArchiveInputStreamを作成して、canReadEntryData()メソッドを利用できるようにします。canReadEntryData()は完全に正常に機能します。通常のファイルではtrueを返しますが、ZipArchiveInputStreamからコンテンツを読み取ることができません。

助けてください。どこが間違っているのかを教えてください。

4

2 に答える 2

2

ZipArchiveInputStreamvsZipFile

公式ドキュメントに記載されているようZipArchiveInputStreamに、いくつかの制限があるようです。

ZIPアーカイブは、アーカイブエントリを順番に保存し、アーカイブの最後にすべてのエントリのレジストリを含みます。アーカイブに同じ名前の複数のエントリが含まれ、レジストリ(中央ディレクトリと呼ばれる)に実際に使用されるエントリ(存在する場合)を決定させることは許容されます。

さらに、ZIP形式では、特定の情報が中央ディレクトリ内にのみ保存され、エントリ自体と一緒には保存されません。これは次のとおりです。

  • 内部および外部属性
  • 異なるまたは追加の追加フィールド

これは、シークできないストリームを読み取っているときに、ZIP形式を実際に正しく解析できないことを意味します。これは、ZipArchiveInputStream 強制的に行われることです。結果としてZipArchiveInputStream

  • 中央ディレクトリの一部ではなく、アーカイブの一部と見なされるべきではないエントリを返す場合があります。
  • 同じ名前の複数のエントリを返す場合があります。
  • 内部または外部の属性を返しません。
  • 不完全な余分なフィールドデータを返す場合があります。

ZipArchiveInputStreamこれらの制限を。と共有し java.util.zip.ZipInputStreamます。

ZipFile最初に中央ディレクトリを読み取り、ZIPアーカイブに関する正確で完全な情報を提供できます。

ZIPアーカイブは、データ記述子と呼ばれる機能を知っています。これは、エントリのデータの後にエントリの長さを格納する方法です。これは、サイズ情報を中央ディレクトリから取得できる場合、またはデータ自体がそれが完了したことを通知できる場合にのみ確実に機能します。これは、DEFLATED圧縮アルゴリズムを使用して圧縮されたデータに当てはまります。

ZipFile中央ディレクトリにアクセスでき、データ記述子を使用してエントリを確実に抽出できます。ZipArchiveInputStreamエントリがDEFLATEDである限り、同じことが当てはまり ます。STOREDの場合、エントリZipArchiveInputStreamは次のエントリが見つかるまで先読みを試みることができますが、このアプローチは安全ではなく、コンストラクター引数によって明示的に有効にする必要があります。

結論:

可能であれば、常によりも優先する必要がありZipFileますZipArchiveInputStream

私は、ZipFile上記の文は、 :InputStreamを使用して作成されたの使用を意味すると信じています。ZipFile

InputStream is = zipFile.getInputStream(zipArchiveEntry);

于 2013-02-21T06:19:23.200 に答える
1

このコードサンプルは、commonscompressを使用してZipを読み取るのに役立つと思います

            ZipFile zipFile = new ZipFile("C:\\test.zip");
            byte[] buf = new byte[65536];
            Enumeration<?> entries = zipFile.getEntries();
            while (entries.hasMoreElements()) {
                ZipArchiveEntry zipArchiveEntry = (ZipArchiveEntry) entries.nextElement();
                int n;
                InputStream is = zipFile.getInputStream(zipArchiveEntry);
                ZipArchiveInputStream zis = new ZipArchiveInputStream(is);
                if (zis.canReadEntryData(zipArchiveEntry)) {
                    while ((n = is.read(buf)) != -1) {
                        if (n > 0) {
                            System.out.println(new String(buf));
                        }
                    }
                }
                zis.close();
            }
于 2013-02-21T06:31:10.703 に答える