Pregunta

Me pregunto si alguien puede arrojar algo de luz sobre un tema que me está volviendo loco:

Estoy escribiendo una clase de prueba de descompresión de compresión. Para probarlo, estoy serializando un conjunto de datos en un flujo de memoria, comprimiéndolo, descomprimiéndolo y comparando los resultados.

La compresión está bien, pero la no compresión es donde golpea la suciedad. Esta es la función de descompresión:

    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 búfer de tamaño 65536, el flujo descomprimido siempre devuelve un byte menos de lo que se descomprimió.

Ahora, esto me lleva al segundo problema con el que estoy luchando. Con algunos tamaños de búfer, uncompressStream.Read devuelve 0, aunque todavía hay datos comprimidos por extraer.

Para estos casos, deflateStream.Read (s) solo una vez en el bucle do {} y luego devuelve una secuencia sin comprimir igual a buffersize, si aumenta el buffersize en un solo byte, todo está bien (excepto el byte que falta) .

Salida para tamaño de archivo de 65536: (los datos originales sin comprimir son 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 of 189544 (Algunos números mágicos donde está el código de los tanques)

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

También tenga en cuenta la tercera lectura del tamaño de buffers 65536 ex: bytesRead: [58472] Claramente, esto también debería ser 65536, ya que aún quedan datos en el búfer.

Cualquier idea será muy bien apreciada.

tia

  • Jaco
¿Fue útil?

Solución

Siempre debe llamar a Close () en flujos de compresión. Tenga en cuenta que Flush () no es suficiente . Sospecho que debido a esto, a la secuencia de desinflado le faltan datos.

Otros consejos

Mis poderes psíquicos me dicen que, de hecho, tienen una implementación de descompresión en funcionamiento, pero se han olvidado de vaciar el flujo de compresión antes.

Bueno, no pude detectar tu problema, pero sigo algún código que escribí hace algún tiempo para 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);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top