Décompressez le fichier de données avec DeflateStream

Je vais avoir de la difficulté à lire un comprimé (dégonflé) fichier de données à l'aide de C# .NET DeflateStream(..., CompressionMode.Decompress). Le fichier a été écrit plus tôt à l'aide de DeflateStream(..., CompressionMode.Compress), et il semble être très bien (je peux même le décompresser à l'aide d'un programme Java).

Cependant, la première Read() appel sur le flux d'entrée pour décompresser/gonfler les données compressées renvoie une longueur de zéro (fin de fichier).

Ici est le conducteur principal, qui est utilisé pour la compression et la décompression:

public void Main(...)
{
    Stream  inp;
    Stream  outp;
    bool    compr;  

    ...
    inp = new FileStream(inName, FileMode.Open, FileAccess.Read);
    outp = new FileStream(outName, FileMode.Create, FileAccess.Write);  

    if (compr)
        Compress(inp, outp);
    else
        Decompress(inp, outp);  

    inp.Close();
    outp.Close();
}

Voici le code de base pour la décompression, qui est ce qui est défectueux:

public long Decompress(Stream inp, Stream outp)
{
    byte[]  buf = new byte[BUF_SIZE];
    long    nBytes = 0;  

    //Decompress the contents of the input file
    inp = new DeflateStream(inp, CompressionMode.Decompress);  

    for (;;)
    {
        int   len;  

        //Read a data block from the input stream
        len = inp.Read(buf, 0, buf.Length);    //<<FAILS
        if (len <= 0)
            break;  

        //Write the data block to the decompressed output stream
        outp.Write(buf, 0, len);
        nBytes += len;
    }  

    //Done
    outp.Flush();
    return nBytes;
}

L'appel a été FAILS renvoie toujours zéro. Pourquoi? Je sais qu'il faut que ce soit quelque chose de simple, mais je ne suis pas le voir.

Voici le code de base pour la compression, qui fonctionne bien, et est presque exactement la même que la méthode de décompression avec les noms inversés:

public long Compress(Stream inp, Stream outp)
{
    byte[]  buf = new byte[BUF_SIZE];
    long    nBytes = 0;  

    //Compress the contents of the input file
    outp = new DeflateStream(outp, CompressionMode.Compress);  

    for (;;)
    {
        int   len;  

        //Read a data block from the input stream
        len = inp.Read(buf, 0, buf.Length);
        if (len <= 0)
            break;  

        //Write the data block to the compressed output stream
        outp.Write(buf, 0, len);
        nBytes += len;
    }  

    //Done
    outp.Flush();
    return nBytes;
}  

Résolu

Après avoir vu la solution correcte, le constructeur déclaration doit être modifié pour:

inp = new DeflateStream(inp, CompressionMode.Decompress, true);

qui maintient le sous-jacent flux d'entrée s'ouvrir, et la ligne suivante doit être ajoutée à la suite de la inp.Flush() appel:

inp.Close();

La Close() appelle les forces de l'deflater flux de vider ses tampons internes. Le true drapeau empêche de fermer le flux sous-jacent, qui est fermée plus tard dans Main(). Les mêmes modifications doivent également être apportées à la Compress() méthode.

OriginalL'auteur David R Tribble | 2009-10-06