Pergunta

Tenho um aplicativo que envia dados coletados de uma fonte de dados no meu PC (por exemplo, Excel ou Access) para um aplicativo receptor em um tablet Android.Estou em fase de teste para compactar os dados antes de serem enviados e descompactá-los após serem recebidos.Estou usando GZIP para isso, com DotNetZip no lado C# e a classe GZIPInputStream integrada no lado Java.

Estou tendo problemas para fazê-lo funcionar corretamente.Quando faço um teste só de um lado (compactando e descompactando para ver se os dados permanecem intactos), está tudo bem.Funciona em C# e Java.Mas quando chego ao ponto em que os dados são enviados e recebidos, me deparo com este problema:"Formato desconhecido (número mágico EF1F)." Eu já vi outras postagens para que isso foi discutido, mas as respostas não parecem ajudar.

Aqui está o código que estou usando para compactar no lado C#:

public void compressData() {
    byte[] buffer = Ionic.Zlib.GZipStream.CompressBuffer(this.RawStreamData.ToArray());
    this.RawStreamData = new MemoryStream(buffer);
}

E aqui está o código que estou usando para descompactar no lado Java.Como os dados são lidos por um BufferedReader, preciso converter inicialmente de char[] para byte[]:

public NetMessage decompressMsg(NetMessage nMsg) throws IOException {
    ByteArrayOutputStream baOut = new ByteArrayOutputStream();
    OutputStreamWriter osWriter = new OutputStreamWriter(baOut);
    osWriter.write(nMsg.getRawMsg());  //.getRawMsg() returns a char[] of the raw data
    osWriter.close();
    ByteArrayInputStream baIn = new ByteArrayInputStream(baOut.toByteArray());
    GZIPInputStream gzIn = new GZIPInputStream(baIn);
    byte[] buffer = new byte[128];
    int nReadBytes = gzIn.read(buffer);
    String sDecompMsg = new String(buffer);

    while (nReadBytes > -1) {
        buffer = new byte[128];
        nReadBytes = gzInput.read(buffer);
        String sTemp = new String(buffer);
        sDecompMsg += sTemp;
    }

    nMsg.setRawMsg(sDecompMsg.toCharArray());

    return nMsg;
}

Isso lança uma exceção quando tento construir o GZIPInputStream.Já sei que a maneira como estou reconstruindo a mensagem do buffer descompactado resultante está errada (apenas nos testes no lado Java), mas esse é um problema que preciso resolver primeiro!:) Qualquer ajuda seria apreciada.Suspeito que possa ter algo a ver com as configurações do nível de compactação;em C# estou usando o padrão, mas AFAIK não existe tal configuração no lado Java.O BufferedReader é criado com uma codificação ASCII.

Foi útil?

Solução

Como os dados são lidos por um BufferedReader, preciso converter inicialmente de char[] para byte[]:

Aquilo é um enorme problema.Você compacta os dados.São dados binários arbitrários.Você deve absolutamente não tratá-lo como texto.Não está claro para mim o que NetMessage é, mas basicamente você precisará obter acesso aos dados binários brutos que está enviando pela rede - caso contrário, você não terá chance de descompactá-los.

Outras dicas

"O BufferredReader é criado com uma codificação ASCII." Então é óbvio que seu programa não pode funcionar.Os dados compactados GZip usam todos os bits dos bytes, portanto, interpretá-los como ASCII causa perda de dados.Além disso, você converte os caracteres de volta em uma matriz de bytes sem especificar uma codificação, de modo que o padrão do sistema seja usado, o que está além do controle do seu programa.Você deve usar a mesma codificação para ambas as conversões e deve reter todas as informações de todos os bits, por exemplo.usar iso-latin-1 resolveria o problema.Mas seria muito melhor corrigir essa falha de conversão de bytes em caracteres e de volta em bytes.

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