我尝试使用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)
有什么想法吗?
提前感谢您的任何帮助!
答案 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没有任何好处。