通过网络将Gzip数据从C#发送到Java
我有一个应用程序,可以将从PC上的数据源(比如Excel或Access)收集的数据发送到Android平板电脑上的接收应用程序。我正处于测试阶段,在发送数据之前对其进行压缩,然后在接收数据之后对其进行解压缩。为此,我使用GZIP,在C#端使用DotNetZip,在Java端使用内置的GZIPInputStream类 我在让它正常工作方面遇到了问题。当我只在一侧进行测试(压缩和解压缩以查看数据是否保持完整)时,一切正常。它可以在C#和Java上运行。但当我谈到发送和接收数据时,我遇到了这样一个问题:“未知格式(魔法数字ef1f)。”我曾看到其他SO帖子讨论过这一点,但答案似乎没有帮助 下面是我用来压缩C端的代码: 下面是我用来在Java端解压的代码。因为数据是由BufferedReader读入的,所以我必须首先从char[]转换为byte[]:通过网络将Gzip数据从C#发送到Java,c#,java,compression,gzip,dotnetzip,C#,Java,Compression,Gzip,Dotnetzip,我有一个应用程序,可以将从PC上的数据源(比如Excel或Access)收集的数据发送到Android平板电脑上的接收应用程序。我正处于测试阶段,在发送数据之前对其进行压缩,然后在接收数据之后对其进行解压缩。为此,我使用GZIP,在C#端使用DotNetZip,在Java端使用内置的GZIPInputStream类 我在让它正常工作方面遇到了问题。当我只在一侧进行测试(压缩和解压缩以查看数据是否保持完整)时,一切正常。它可以在C#和Java上运行。但当我谈到发送和接收数据时,我遇到了这样一个问题
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[]
。非常感谢。