web-dev-qa-db-fra.com

Exception: fin inattendue du flux d'entrée ZLIB

Il y a un problème avec GZIPInputStream ou GZIPOutputStream. Veuillez simplement lire le code suivant (ou l'exécuter et voir ce qui se passe):

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

Il crée un fichier test.dat, écrit un seul octet 10 formatage par GZIP, et lire l'octet dans le même fichier au même format.

Et voici ce que je l'ai fait fonctionner:

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)

La ligne de lecture semble aller dans le mauvais sens pour une raison quelconque.

J'ai googlé l'erreur Unexpected end of ZLIB input stream et a trouvé des rapports de bogues à Oracle, qui ont été publiés vers 2007-2010. Je suppose donc que le bogue persiste d'une certaine manière, mais je ne suis pas sûr que mon code soit correct, alors laissez-moi le poster ici et écouter vos conseils. Merci!

20
Ryoichiro Oka

Vous devez appeler close() sur le GZIPOutputStream avant d'essayer de le lire. Les octets finaux du fichier ne seront écrits que lorsque le fichier sera réellement fermé. (Ceci est indépendant de toute mise en mémoire tampon explicite dans la pile de sortie. Le flux ne sait compresser et écrire les derniers octets que lorsque vous lui demandez de se fermer. Une flush() n'aidera probablement pas ... bien que l'appel de finish() au lieu de close() devrait fonctionner. Regardez les javadocs.)

Voici le bon code (en 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());
    }
}

(Je n'ai pas correctement implémenté la gestion des ressources. Ne traitez pas cela comme un exemple de "bon code".)

30
Stephen C