Domanda

Mi chiedo se qualcuno possa far luce su un problema che mi sta facendo impazzire:

Sto scrivendo una classe di test di decompressione compressiva. Per provarlo, sto serializzando un set di dati in un flusso di memoria, lo comprime, lo decomprimo e confronto i risultati.

La compressione va bene, ma la compressione è dove colpisce la terra. Questa è la funzione di decompressione:

    public static Stream GetUncompressedStreamCopy(Stream inStream)
    {
      Stream outStream = new MemoryStream();

      inStream.Position = 0;

      DeflateStream uncompressStream = new DeflateStream(inStream, 
        CompressionMode.Decompress, true);

      byte[] buffer = new byte[65536];

      int totalread = 0;
      int bytesread = 0;


      do {
        bytesread = uncompressStream.Read(buffer, 0, buffer.Length);
        totalread += bytesread;
        outStream.Write(buffer, 0, bytesread);
        Console.WriteLine("bytesRead: [{0}]\t outStream.Length [{1}]",
        bytesread, outStream.Length);
      } while (bytesread > 0);


      Console.WriteLine("total bytes read [{0}]", totalread);
      outStream.Flush();
      return outStream;
}

Con un buffer di dimensioni 65536, il flusso decompresso restituisce sempre un byte in meno rispetto a quello non compresso.

Ora questo mi porta al secondo numero con cui sto combattendo. Con alcune dimensioni del buffer, uncompressStream.Read restituisce 0 anche se ci sono ancora dati compressi da estrarre.

In questi casi, deflateStream.Read (s) solo una volta nel ciclo do {} e quindi restituisce un flusso non compresso uguale a dimensione buffer, se si aumenta la dimensione buffer di un singolo byte tutto va bene (tranne il byte mancante) .

Output per buffersize di 65536: (i dati non compressi originali sono 207833)

bytesRead: [65536]       outStream.Length [65536]
bytesRead: [65536]       outStream.Length [131072]
bytesRead: [58472]       outStream.Length [189544]
bytesRead: [18288]       outStream.Length [207832]
bytesRead: [0]           outStream.Length [207832]
total bytes read [207832]

buffersize del 189544 (alcuni numeri magici in cui il serbatoio di codice)

bytesRead: [189544]      outStream.Length [189544]
bytesRead: [0]           outStream.Length [189544]
total bytes read [189544]
Unompressed stream size 189544

Nota anche la terza lettura di buffersize 65536 ex: bytesLeggi: [58472] Chiaramente questo dovrebbe essere anche 65536 poiché ci sono ancora dei dati sul buffer?

Qualsiasi idea sarà molto apprezzata.

tia

  • Jaco
È stato utile?

Soluzione

Dovresti sempre chiamare Close () sui flussi di compressione. Tieni presente che Flush () non è non sufficiente . Ho il sospetto che a causa di ciò il flusso di deflazione sia privo di dati.

Altri suggerimenti

I miei poteri psichici mi dicono che in realtà hai un'implementazione decompressiva funzionante, ma hai dimenticato di svuotare il flusso di compressione prima.

Beh, non sono riuscito a individuare il tuo problema, ma segui un po 'di codice che ho scritto qualche tempo fa per ICSharpCode .SharpZipLib ;

byte[] compressedData;
using(MemoryStream ms = new MemoryStream())
{
    Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION, true);
    Stream s = new DeflaterOutputStream(ms, deflater);
    s.Write(sendData, 0, sendData.Length);
    s.Close();
    compressedData = (byte[])ms.ToArray();
}

// ...

MemoryStream inflated = new MemoryStream();
using (Stream inflater = new InflaterInputStream(
    inputStream, new Inflater(true)))
{
    int count = 0;
    byte[] deflated = new byte[4096];
    while ((count = inflater.Read(deflated, 0, deflated.Length)) != 0)
    {
        inflated.Write(deflated, 0, count);
    }
    inflated.Seek(0, SeekOrigin.Begin);
}
byte[] content = new byte[inflated.Length];
inflated.Read(content, 0, content.Length);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top