通过网络将Gzip数据从C#发送到Java

通过网络将Gzip数据从C#发送到Java,c#,java,compression,gzip,dotnetzip,C#,Java,Compression,Gzip,Dotnetzip,我有一个应用程序,可以将从PC上的数据源(比如Excel或Access)收集的数据发送到Android平板电脑上的接收应用程序。我正处于测试阶段,在发送数据之前对其进行压缩,然后在接收数据之后对其进行解压缩。为此,我使用GZIP,在C#端使用DotNetZip,在Java端使用内置的GZIPInputStream类 我在让它正常工作方面遇到了问题。当我只在一侧进行测试(压缩和解压缩以查看数据是否保持完整)时,一切正常。它可以在C#和Java上运行。但当我谈到发送和接收数据时,我遇到了这样一个问题

我有一个应用程序,可以将从PC上的数据源(比如Excel或Access)收集的数据发送到Android平板电脑上的接收应用程序。我正处于测试阶段,在发送数据之前对其进行压缩,然后在接收数据之后对其进行解压缩。为此,我使用GZIP,在C#端使用DotNetZip,在Java端使用内置的GZIPInputStream类

我在让它正常工作方面遇到了问题。当我只在一侧进行测试(压缩和解压缩以查看数据是否保持完整)时,一切正常。它可以在C#和Java上运行。但当我谈到发送和接收数据时,我遇到了这样一个问题:“未知格式(魔法数字ef1f)。”我曾看到其他SO帖子讨论过这一点,但答案似乎没有帮助

下面是我用来压缩C端的代码:

下面是我用来在Java端解压的代码。因为数据是由BufferedReader读入的,所以我必须首先从char[]转换为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;
}
当我试图构造GZIPInputStream时,它抛出异常。我已经知道我从结果解压缩的缓冲区重建消息的方式是错误的(仅从Java端的测试中),但这是我需要首先解决的一个问题:)任何帮助都将不胜感激。我怀疑这可能与压缩级别设置有关;在C#中,我使用默认设置,但在Java端没有这样的设置。BufferedReader是使用ASCII编码创建的

因为数据是由BufferedReader读入的,所以我必须首先从char[]转换为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;
}
这是个大问题。你已经压缩了数据。这是任意的二进制数据。你绝对不应该把它当作文本。我不清楚什么是
NetMessage
,但基本上您需要访问通过网络发送的原始二进制数据,否则就没有机会对其进行解压缩

因为数据是由BufferedReader读入的,所以我必须首先从char[]转换为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;
}

这是个大问题。你已经压缩了数据。这是任意的二进制数据。你绝对不应该把它当作文本。我不清楚什么是
NetMessage
,但基本上你需要访问通过网络发送的原始二进制数据,否则你就没有机会对其进行解压缩。

“BufferedReader是用ASCII编码创建的。”很明显,你的程序无法工作。GZip压缩数据使用所有字节位,所以将其解释为ASCII会导致数据丢失。此外,在不指定编码的情况下将字符转换回字节数组,因此使用系统的默认值,这超出了程序的控制范围。您必须对两种转换使用相同的编码,并且必须保留所有位的所有信息,例如,使用iso-latin-1即可。但是,修复将字节转换为字符并返回字节的缺陷要好得多。

“BufferedReader是用ASCII编码创建的。”很明显,您的程序无法工作。GZip压缩数据使用所有字节位,所以将其解释为ASCII会导致数据丢失。此外,在不指定编码的情况下将字符转换回字节数组,因此使用系统的默认值,这超出了程序的控制范围。您必须对两种转换使用相同的编码,并且必须保留所有位的所有信息,例如,使用iso-latin-1即可。但修复将字节转换为字符并返回字节的缺陷要好得多。

NetMessage
是一种包装器,用于将数据消息从PC来回发送到平板电脑。
.getRawMsg()
方法将消息的原始数据返回为
char[]
,这实际上是从C端压缩的数据。由于
gzip输入流
需要一个底层流才能工作,因此我使用
OutputStreamWriter
char[]
转换为
byte[]
。这个过程是否以某种方式将原始数据转换为文本?@F.Ali:如果它以
char[]
的形式返回数据,那么它不是原始数据,而是文本。原始数据是二进制的。
NetMessage
是否由您控制?如果是这样,听起来需要修复。是的,看起来我需要重新编写
NetMessage
,以使用
byte[]
。谢谢。
NetMessage
是一个包装器,用于将数据消息从PC发送到平板电脑。
.getRawMsg()
方法将消息的原始数据返回为
char[]
,这实际上是从C端压缩的数据。由于
gzip输入流
需要一个底层流才能工作,因此我使用
OutputStreamWriter
char[]
转换为
byte[]
。这个过程是否以某种方式将原始数据转换为文本?@F.Ali:如果它以
char[]
的形式返回数据,那么它不是原始数据,而是文本。原始数据是二进制的。
NetMessage
是否由您控制?如果是这样,听起来需要修复。是的,看起来我需要重新编写
NetMessage
,以使用
byte[]
。非常感谢。