GZIPInputStream 无法在接收器端解码(设置的代码长度无效)


我正在尝试使用 GZIPOutputStream 在

客户端中对字符串进行编码,然后使用 GZIPOutputStream 在服务器中解码字符串。

客户端的端代码(在初始套接字连接建立之后(为:

// ... Establishing connection, getting a socket object.
// ... Now proceeding to send data using that socket:
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
String message = "Hello World!";
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(out);
gzip.write(message);
gzip.close();
String encMessage = out.toString();
out.writeInt(encMessage.getBytes().length);
out.write(encMessage.getBytes());
out.flush();

和服务器的端代码(再次,在建立连接后(:

DataInputStream input = new DataInputStream(socket.getInputStream());
int length = input.readInt();
byte[] buffer = new byte[length];
input.readFully(buffer);
GZIPInputStream gz = new GZIPInputStream(new ByteArrayInputStream(buffer));
BufferedReader r = new BufferedReader(new InputStreamReader(gz));
String s = "";
String line;
while ((line = r.readLine()) != null) 
{
    s += line;
}

我检查了一下,缓冲区长度(即编码消息的大小(正确传递,因此传输了正确的字节数。但是,我得到了这个:

java.util.zip.ZipException: invalid code lengths set
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:164)
at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:117)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:122)
at parsing.ReceiveResponsesTest$TestReceiver.run(ReceiveResponsesTest.java:147)
at java.lang.Thread.run(Thread.java:745)

有什么想法吗?

提前感谢您的任何帮助!

你在ByteArrayOutputStream上调用toString() - 这是不正确的,它打开了各种字符编码问题,这些问题可能会在这里咬你。您需要改为调用toByteArray

byte[] encMessage = out.toByteArray();
out.writeInt(encMessage.length);
out.write(encMessage);

细节:

如果您使用 toString() ,Java 将以您的平台默认字符编码对您的字节进行编码。这可能是一些Windows代码页,UTF-8或其他什么。但是,并非所有字符都可以正确编码,有些字符将被替代字符替换 - 也许是一个问号。不知道细节,很难说。

但无论如何,将字节数组编码为 String,然后在写出时再次将其解码为字节数组,很可能会更改字节数组中的数据。而且没有必要这样做,你可以直接获取字节数组,如上面的代码所示。

你到底为什么要沉迷于所有这些复杂情况?你可以把它全部简化为:

GZIPOutputStream gzip = new GZIPOutputStream(socket.getOutputStream());
DataOutputStream out = new DataOutputStream(gzip);
String message = "Hello World!";    
out.writeUTF(message);
out.close();
// ...    
GZIPInputStream gz = new GZIPInputStream(new ByteArrayInputStream(socket.getInputStream()));
DataInputStream input = new DataInputStream(gz);
String line = input.readUTF();

我进一步指出,您的代码实际上并没有编译。我还要指出,除非消息大几个数量级,否则对GZipping没有任何好处。

最新更新