什么可能导致在GZip压缩数据流中创建错误的EOF

时间:2010-08-10 10:27:58

标签: java .net gzip

我们将服务器(在Windows上运行的.Net)中的数据流式传输到客户端(用Ubuntu运行的Java编写)。数据采用XML格式。在尝试解压缩流时,Java客户端偶尔会抛出意外的EOF。消息内容总是变化的并且是用户驱动的。客户端的响应也使用GZip压缩。这永远不会失败,似乎坚如磐石。客户端的响应由系统控制。

是否有可能某些字符排列或某些特殊字符会产生错误的EOF标记?它可能与白空间有关吗? GZip适合压缩XML吗?

我假设从输入/输出流读取和写入的代码有效,因为我们偶尔会得到这个异常,当我们检查用户数据的时候似乎有特殊字符(这就是我问的原因)问题),例如'@'符号。

有什么想法吗?

更新: 请求的实际代码。我认为这不是因为我曾经去过几个网站以获得有关此问题的帮助,而且他们或多或少拥有相同的代码。有些网站提到了附加的GZip。与GZip创建多个细分市场有什么关系?

public String receive() throws IOException {

    byte[] buffer = new byte[8192];
    ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);

    do {
        int nrBytes = in.read(buffer);
        if (nrBytes > 0) {
            baos.write(buffer, 0, nrBytes);
        }
    } while (in.available() > 0);
    return compressor.decompress(baos.toByteArray());
}
   public String decompress(byte[] data) throws IOException {
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    ByteArrayInputStream in = new ByteArrayInputStream(data);

    try {
        GZIPInputStream inflater = new GZIPInputStream(in); 
        byte[] byteBuffer = new byte[8192];
        int r;
        while((r = inflater.read(byteBuffer)) > 0 ) {
            buffer.write(byteBuffer, 0, r); 
        }
    } catch (IOException e) {
        log.error("Could not decompress stream", e);
        throw e;
    }
    return new String(buffer.toByteArray());
}

起初我以为我在流中阅读的方式肯定有问题,我想也许我没有正确循环。然后,我生成了大量数据进行流式处理并检查它是否正在循环。事实上它们很少发生,而且到目前为止还没有重现性,这让我相信它是内容而不是场景。但在这一点上,我完全感到困惑,而且我知道这是代码。

再次感谢大家。

更新2:

根据要求提供.Net代码:

Dim DataToCompress = Encoding.UTF8.GetBytes(Data)
Dim CompressedData = Compress(DataToCompress)

将原始数据转换为字节。然后它被压缩了

      Private Function Compress(ByVal Data As Byte()) As Byte()
            Try
                Using MS = New MemoryStream()
                    Using Compression = New GZipStream(MS, CompressionMode.Compress)
                        Compression.Write(Data, 0, Data.Length)
                        Compression.Flush()
                        Compression.Close()
                        Return MS.ToArray()
                    End Using
                End Using
            Catch ex As Exception
                Log.Error("Error trying to compress data", ex)
                Throw
            End Try
        End Function

更新3:还添加了更多java代码。 in变量是从socket.getInputStream()

返回的InputStream

3 个答案:

答案 0 :(得分:1)

当然不应该由于所涉及的数据 - 流处理二进制数据,因此根本不应该有任何可能性。

但是,如果没有看到您的代码,很难肯定地说。我的第一个停靠点是检查你正在使用的任何地方InputStream.read() - 检查你是否正确使用了返回值,而不是假设一次调用read()将填充缓冲区。 / p>

如果你能提供一些代码,那将会有很多帮助......

答案 1 :(得分:0)

我怀疑由于某种原因,数据被改变了,将其视为文本,而不是二进制,因此它可能是\ n转换或代码页更改。

如何在两个系统之间传输压缩流?

答案 2 :(得分:0)

这不可能。 TCP中的EOF作为带外FIN段传送,而不是通过数据传送。