web-dev-qa-db-ja.com

例外:ZLIB入力ストリームの予期しない終了

GZIPInputStreamまたはGZIPOutputStreamに何か問題があります。次のコードを読んでください(または実行して何が起こるかを確認してください):

def main(a: Array[String]) {
    val name = "test.dat"
    new GZIPOutputStream(new FileOutputStream(name)).write(10)
    println(new GZIPInputStream(new FileInputStream(name)).read())
}

ファイルtest.datを作成し、GZIPで単一バイト10フォーマットを書き込み、同じファイルを同じフォーマットで読み取ります。

そして、これは私がそれを実行したものです:

Exception in thread "main" Java.io.EOFException: Unexpected end of ZLIB input stream
    at Java.util.Zip.InflaterInputStream.fill(Unknown Source)
    at Java.util.Zip.InflaterInputStream.read(Unknown Source)
    at Java.util.Zip.GZIPInputStream.read(Unknown Source)
    at Java.util.Zip.InflaterInputStream.read(Unknown Source)
    at nbt.Test$.main(Test.scala:13)
    at nbt.Test.main(Test.scala)

何らかの理由で読書行が間違った方向に進んでいるようです。

エラーUnexpected end of ZLIB input streamをグーグルで検索し、2007-2010年頃に発行されたOracleへのバグレポートを見つけました。したがって、バグはまだ何らかの形で残っていると思いますが、私のコードが正しいかどうかはわかりません。ありがとうございました!

20
Ryoichiro Oka

読み取る前に、GZIPOutputStreamclose()を呼び出す必要があります。ファイルの最後のバイトは、ファイルが実際に閉じられたときにのみ書き込まれます。 (これは、出力スタックの明示的なバッファリングとは無関係です。ストリームは、閉じるように指示した場合に最後のバイトのみを圧縮して書き込むことを知っています。flush()はおそらく役に立ちません... finish()の代わりにclose()を呼び出す必要がありますがjavadocsをご覧ください。)

これが正しいコードです(Javaで)。

package test;

import Java.io.FileInputStream;
import Java.io.FileNotFoundException;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.util.Zip.GZIPInputStream;
import Java.util.Zip.GZIPOutputStream;

public class GZipTest {

    public static void main(String[] args) throws FileNotFoundException, IOException {
        String name = "/tmp/test";
        GZIPOutputStream gz = new GZIPOutputStream(new FileOutputStream(name));
        gz.write(10);
        gz.close();
        System.out.println(new GZIPInputStream(new FileInputStream(name)).read());
    }
}

(リソース管理を適切に実装していません。これを「良いコード」の例として扱わないでください。)

30
Stephen C