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

时间:2017-02-06 04:43:02

标签: java sockets gzipinputstream gzipoutputstream

我尝试使用GZIPOutputStream在客户端编码String,然后使用GZIPOutputStream解码服务器中的String。

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

// ... 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)

有什么想法吗?

提前感谢您的任何帮助!

2 个答案:

答案 0 :(得分:2)

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

byte[] encMessage = out.toByteArray();

out.writeInt(encMessage.length);
out.write(encMessage);

细节:

如果使用toString(),Java将使用您的平台默认字符编码对您的字节进行编码。这可能是一些Windows代码页,UTF-8或诸如此类的东西。 然而,并非所有字符都可以正确编码,有些字符可能会替换为替代字符 - 也许是问号。在不知道细节的情况下,很难说清楚。

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

答案 1 :(得分:1)

为什么你会沉迷于所有这些并发症?你可以减少这一切:

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没有任何好处。

相关问题