Pergunta

Eu não entendo. Eu uso uma abordagem semelhante/mesma há muitos anos e nunca experimentei isso.

Por alguma razão, que eu não atendei até hoje, uma ida e volta do GZIP resulta em 1 ou mais bytes sendo truncados ou dados sendo distorcidos.

Escrevi um teste simples para verificar se algo mais não está afetando.

Isso sempre falha com uma 'incompatibilidade de comprimento'.

Alguém pode me conformar que eu não sou louco? :)

Obrigado

Leppie

TESTE

using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;

class Program
{
  const int BUFFER_SIZE = 8192;

  static void Main(string[] args)
  {
    var filename = args[0];
    var filedata = File.ReadAllBytes(filename);
    var cmp = Compress(filedata);
    var dec = Decompress(cmp);

    Assert(filedata, dec);

    Console.ReadLine();
  }

  static void Assert(byte[] orig, byte[] data)
  {
    if (orig.Length != data.Length)
    {
      Debug.Fail("length mismatch");
    }
    for (int i = 0; i < orig.Length; i++)
    {
      Debug.Assert(orig[i] == data[i], "data mismatch");
    }
  }

  static byte[] Compress(byte[] data)
  {
    var input = new MemoryStream(data);
    var output = new MemoryStream();

    var s = new GZipStream(output, CompressionMode.Compress);
    byte[] buffer = new byte[BUFFER_SIZE];
    int read = 0;
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
    {
      s.Write(buffer, 0, read);
    }

    return output.ToArray();
  }

  static byte[] Decompress(byte[] data)
  {
    var input = new MemoryStream(data);
    var s = new GZipStream(input, CompressionMode.Decompress);

    var output = new MemoryStream();
    byte[] buffer = new byte[BUFFER_SIZE];
    int read = 0;
    while ((read = s.Read(buffer, 0, buffer.Length)) > 0)
    {
      output.Write(buffer, 0, read);
    }

    return output.ToArray();
  }
}

Eu tentei com fechar os fluxos também, com tamanhos de buffer diferentes, o mesmo resultado.

Foi útil?

Solução

Ok, encontrei o problema.

Você precisa fechar o fluxo de compressão antes de recuperar os bytes.

Por exemplo:

s.Close();
return output.ToArray();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top