Java 中客户端/服务器传输的压缩字符串
我使用专有的客户端/服务器消息格式来限制我可以通过网络发送的内容。我无法发送序列化对象,我必须将消息中的数据存储为字符串。我发送的数据是大的逗号分隔值,我想在将数据作为字符串打包到消息中之前对其进行压缩。
我尝试使用 Deflater/Inflater 来实现这一点,但在这个过程中我遇到了困难。
我使用以下两种方法来放气/充气。但是,将 compressString() 方法的结果传递给 decompressStringMethod() 将返回 null 结果。
public String compressString(String data) {
Deflater deflater = new Deflater();
byte[] target = new byte[100];
try {
deflater.setInput(data.getBytes(UTF8_CHARSET));
deflater.finish();
int deflateLength = deflater.deflate(target);
return new String(target);
} catch (UnsupportedEncodingException e) {
//TODO
}
return data;
}
public String decompressString(String data) {
String result = null;
try {
byte[] input = data.getBytes();
Inflater inflater = new Inflater();
int inputLength = input.length;
inflater.setInput(input, 0, inputLength);
byte[] output = new byte[100];
int resultLength = inflater.inflate(output);
inflater.end();
result = new String(output, 0, resultLength, UTF8_CHARSET);
} catch (DataFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
I work with a propriety client/server message format that restricts what I can send over the wire. I can't send a serialized object, I have to store the data in the message as a String. The data I am sending are large comma-separated values, and I want to compress the data before I pack it into the message as a String.
I attempted to use Deflater/Inflater to achieve this, but somewhere along the line I am getting stuck.
I am using the two methods below to deflate/inflate. However, passing the result of the compressString() method to decompressStringMethod() returns a null result.
public String compressString(String data) {
Deflater deflater = new Deflater();
byte[] target = new byte[100];
try {
deflater.setInput(data.getBytes(UTF8_CHARSET));
deflater.finish();
int deflateLength = deflater.deflate(target);
return new String(target);
} catch (UnsupportedEncodingException e) {
//TODO
}
return data;
}
public String decompressString(String data) {
String result = null;
try {
byte[] input = data.getBytes();
Inflater inflater = new Inflater();
int inputLength = input.length;
inflater.setInput(input, 0, inputLength);
byte[] output = new byte[100];
int resultLength = inflater.inflate(output);
inflater.end();
result = new String(output, 0, resultLength, UTF8_CHARSET);
} catch (DataFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
据我所知,您当前的方法是:
getBytes("UTF-8")
将压缩字符串转换为字节数组。此方法的问题在于步骤 3。压缩字节数组时,您创建的字节序列可能不再是有效的 UTF-8。结果将在步骤 3 中出现异常。
解决方案是使用 Base64 等“字节到字符”编码方案,将压缩后的字节转换为可传输的字符串。换句话说,将步骤 3 替换为对 Base64 编码函数的调用,将步骤 6 替换为对 Base64 解码函数的调用。
注意:
编码实际上可能是
增加传输字符串的大小。
From what I can tell, your current approach is:
getBytes("UTF-8")
.new String(bytes, ..., "UTF-8")
.getBytes("UTF-8")
.new String(bytes, ..., "UTF-8")
.The problem with this approach is in step 3. When you compress the byte array, you create a sequence of bytes which may no longer be valid UTF-8. The result will be an exception in step 3.
The solution is to use a "bytes to characters" encoding scheme like Base64 to turn the compressed bytes into a transmissible string. In other words, replace step 3 with a call to a Base64 encode function, and step 6 with a call to a Base64 decode function.
Notes:
encoding is likely to actually
increase the size of the transmitted string.
问题在于您将压缩字节转换为字符串,这会破坏数据。您的
compressString
和decompressString
应该适用于byte[]
编辑:这是修订版本。它有效
编辑2:关于base64。您发送的是字节,而不是字符串。你不需要base64。
The problem is that you convert compressed bytes to a string, which breaks the data. Your
compressString
anddecompressString
should work onbyte[]
EDIT: Here is revised version. It works
EDIT2: And about base64. you're sending bytes, not strings. You don't need base64.
对我来说:自己编写压缩算法很困难,但将二进制写入字符串并不困难。因此,如果我是你,我将正常序列化对象并通过压缩(由 ZipFile 提供)对其进行压缩,然后使用类似 Base64 编码/解码。
我实际上有 BASE64 ENCODE/DECODE 函数。如果你想要的话我可以把它发布在这里。
TO ME: write compress algorithm myself is difficult but writing binary to string is not. So if I were you, I will serialize the object normally and zip it with compression (as provided by ZipFile) then convert to string using something like Base64 Encode/Decode.
I actually have BASE64 ENCODE/DECODE functions. If you wanted I can post it here.
如果你有一段代码似乎默默地失败了,也许你不应该捕获并吞下异常:
但是 decompress 返回 null 的真正原因是因为你的异常处理没有指定如何处理
result< /code> 当您捕获异常时 -
result
保留为 null。您是否检查输出以查看是否发生任何异常?如果我在格式错误的字符串上运行 decompress(),Inflater 会抛出这个
DataFormatException
:If you have a piece of code which seems to be silently failing, perhaps you shouldn't catch and swallow Exceptions:
But the real reason why decompress returns null is because your exception handling doesn't specify what to do with
result
when you catch an exception -result
is left as null. Are you checking the output to see if any Exceptions are occuring?If I run your decompress() on a badly formatted String, Inflater throws me this
DataFormatException
:充气器/放气器不是压缩字符串的解决方案。
我认为 GZIPInputString 和 GZIPOutputString 是压缩字符串的正确工具
Inflator/Deflator is not a solution for compress string.
I think GZIPInputString and GZIPOutputString is the proper tool to compress the string
我遇到了类似的问题,通过 Base64 解码输入解决了这个问题。
即而不是
我尝试过
并且它有效。
I was facing similar issue which was resolved by base64 decoding the input.
i.e instead of
i tried
and it worked.