Pergunta

Eu preciso implementar uma implementação especial ZLib que deve ser executado em .Net e Mono. As mensagens de dados / cordas são recebidos através de uma tomada e, portanto, a soma de verificação está em falta. Trata-se de dados de cadeia matérias, não sobre arquivos.

    unsigned char zlib_header[]={
// custom additional Zlib Id
       'Z',    // Our own ID
// The normal GZIP header
       0x1f,
       0x8b,   // GZIP ID
       0x08,   // Deflated
       0x00,   // Flags
       0, 0, 0, 0, // Timestamp,
       0x00,   // Extra flags
       0x00,   // OS identifier
// afterwards compressed data without a checksum
};

Eu tentei para descomprimir os dados com GZipStream e DeflateStream, mas acho que GZStream falhar por causa da soma de verificação em falta. Eu também tentei várias compensações, mas não teve sorte. A soma de verificação não é utilizado porque os dados são recebidos através de uma tomada de qualquer forma - assim a soma de verificação ZLib seria uma sobrecarga adicional. Eu tenha perdido alguma coisa ou você poderia me explicar como adicionar a soma de verificação e chamar a biblioteca para a direita então ou eu deveria olhar para uma biblioteca parte 3 que suporta Mono e .net? Edit: O desempenho é muito crítico como este feito pelo menos uma vez por segundo. Você recomendaria me no final para usar o C-Lib via Interop? Eu sempre receber Exceção dados inválidos no momento e eu assumo que ela está relacionada com a soma de verificação errada. Este é o código real que eu tentei usar sem sucesso:

const int HeaderSize = 1;
System.IO.MemoryStream ms = new System.IO.MemoryStream(compressedBuffer, HeaderSize, compressedBuffer.Length-HeaderSize);//remove the additional Z from the header
GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress,true);
byte[] deCompressedBytes = new byte[actualBufferLength* 10];
int resultSize=zipStream.Read(deCompressedBytes, 0, actualBufferLength);//get rid of the header      
UTF8Encoding enc = new UTF8Encoding();
string result = enc.GetString(deCompressedBytes, 0, resultSize);
Foi útil?

Solução

Você tem certeza que tem a ver com a soma de verificação?

O checksum de 32 bits não é opcional no formato GZIP. Eu não entendo o que você quer dizer com "os dados são recebidos através da tomada, portanto, a soma de verificação está faltando". Não importa se você obter os dados através de pombo-correio; se é um fluxo GZIP válido, ele deve ter um CRC de 32 bits. Quem ou o que produziu os dados de origem?

Há uma parte opcional na especificação GZIP - a soma de verificação de 16 bits. (A sua inclusão também não se baseia na forma como o fluxo de bytes GZIP foi criado.) A classe System.IO.GZipStream o prazer de aceitar um fluxo GZIP que carece desta CRC16, bem como uma que inclua.

Você tem alguns outros problemas no código. O actualBufferLength em seu código - o que é isso? Certamente não é o tamanho do buffer para armazenar os dados descompactados. Isso é 10x. Mas 10x parece bastante arbitrária. Para dados muito compressíveis, você pode exceder 10x. Eu sugiro que você use uma abordagem em streaming de descompressão.

Quanto a saber se você será capaz de lidar com uma descompressão 1 por segundo, sim, o System.IO.GZipStream vai ser rápido o suficiente para pequenos pedaços suficientes de dados. Há provavelmente não há necessidade de ir a um C / C ++ biblioteca nativa.

ps: A DotNetZip biblioteca inclui um GZipStream que é open source; você pode usá-lo para fora da caixa ou se você quiser, você pode simplesmente pegar o material GZip se isso é tudo que você precisa.

Outras dicas

Basta usar DeflateStream vez de GZipStream.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top