Domanda

Sto usando la zlib.NET per provare e gonfiare i file che sono compressi da zlib (su un box Linux, forse). Ecco cosa sto facendo:

zlib.ZInputStream zinput =
    new zlib.ZInputStream(File.Open(path, FileMode.Open, FileAccess.Read));

while (stopByte != (data = zinput.ReadByte()))
{
  // check data here
}

zinput.Close();

I byte di dati corrispondono ai byte di dati compressi, quindi devo fare qualcosa di sbagliato.

È stato utile?

Soluzione 2

Sembra che io abbia fatto l'errore di presumere che tutti i metodi virtuali fossero stati ignorati, il che non era il caso. Stavo usando zlib.ZInputStream.ReadByte (), che è solo Stream.ReadByte () ereditato, che non si gonfia.

Ho usato invece zlib.ZInputStream.Read () e ha funzionato come dovrebbe.

Altri suggerimenti

Oltre a non usare un " usando " dichiarazione per chiudere il flusso anche di fronte a un'eccezione, mi sembra a posto. I dati sono sicuramente compressi? Sei in grado di decomprimerlo con zlib sulla scatola di Linux?

Dopo aver esaminato il codice sorgente, è piuttosto orribile: una chiamata a int Read (buffer, offset, lunghezza) finirà per chiamare il suo int Read () ad esempio il metodo length . Dato quel tipo di inizio traballante, non sono sicuro che mi fiderei particolarmente del codice, ma mi sarei aspettato che funzionasse almeno leggermente ! Hai provato a utilizzare SharpZipLib ?

Saltando l'intestazione zlib (primi due byte, 78 9C ) e quindi usando DeflateStream integrato in .net ha funzionato per me.

using(var input = File.OpenRead(...))
using(var output = File.Create(...))
{
    // if there are additional headers before the zlib header, you can skip them:
    // input.Seek(xxx, SeekOrigin.Current);

    if (input.ReadByte() != 0x78 || input.ReadByte() != 0x9C)//zlib header
        throw new Exception("Incorrect zlib header");

    using (var deflateStream = new DeflateStream(decryptedData, CompressionMode.Decompress, true))
    {
        deflateStream.CopyTo(output);
    }
}

Il codice qui sotto potrebbe aiutarti ragazzi. Crea un'istanza dell'oggetto e usa le funzioni.

public class FileCompressionUtility
{
    public FileCompressionUtility()
    {
    }

    public static void CopyStream(System.IO.Stream input, System.IO.Stream output)
    {
        byte[] buffer = new byte[2000];
        int len;
        while ((len = input.Read(buffer, 0, 2000)) > 0)
        {
            output.Write(buffer, 0, len);
        }
        output.Flush();
    }

    public void compressFile(string inFile, string outFile)
    {
        System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
        zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outFileStream, zlib.zlibConst.Z_DEFAULT_COMPRESSION);
        System.IO.FileStream inFileStream = new System.IO.FileStream(inFile, System.IO.FileMode.Open);
        try
        {
            CopyStream(inFileStream, outZStream);
        }
        finally
        {
            outZStream.Close();
            outFileStream.Close();
            inFileStream.Close();
        }
    }

    public void uncompressFile(string inFile, string outFile)
    {
        int data = 0;
        int stopByte = -1;
        System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
        zlib.ZInputStream inZStream = new zlib.ZInputStream(System.IO.File.Open(inFile, System.IO.FileMode.Open, System.IO.FileAccess.Read));
        while (stopByte != (data = inZStream.Read()))
        {
            byte _dataByte = (byte)data;
            outFileStream.WriteByte(_dataByte);
        }

        inZStream.Close();
        outFileStream.Close();
    }
}

Guarda il codice di esempio più da vicino, sta copiando i dati da un normale Filestream a ZOutputStream. La decompressione deve avvenire attraverso quel livello.

private void decompressFile(string inFile, string outFile)
{
    System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
    zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outFileStream);
    System.IO.FileStream inFileStream = new System.IO.FileStream(inFile, System.IO.FileMode.Open);          
    try
    {
        CopyStream(inFileStream, outZStream);
    }
    finally
    {
        outZStream.Close();
        outFileStream.Close();
        inFileStream.Close();
    }
}

Di recente ho avuto la sfortuna di distribuire documenti precedentemente usati da php su una varietà di browser e piattaforme tra cui IE7. Una volta ho capito che i documenti erano zlib e non gzip (come si pensava all'epoca) ho usato SharpZipLib nel modo seguente in .NET Framework v4 (sfruttando Stream.CopyTo ):

public static byte[] DecompressZlib(Stream source)
{
    byte[] result = null;
    using (MemoryStream outStream = new MemoryStream())
    {
        using (InflaterInputStream inf = new InflaterInputStream(source))
        {
            inf.CopyTo(outStream);
        }
        result = outStream.ToArray();
    }
    return result;
}

Pensavo di metterlo qui nel caso qualcuno avesse bisogno di aiuto con le classi da usare da SharpZipLib.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top