我们可以轻松地将String
与byte[]
反汇编
String s = "my string";
byte[] b = s.getBytes();
System.out.println(new String(b)); // my string
当涉及压缩时,似乎存在一些问题。假设您有 2 个方法,compress
和 uncompress
(下面的代码工作正常)
public static byte[] compress(String data)
throws UnsupportedEncodingException, IOException {
byte[] input = data.getBytes("UTF-8");
Deflater df = new Deflater();
df.setLevel(Deflater.BEST_COMPRESSION);
df.setInput(input);
ByteArrayOutputStream baos = new ByteArrayOutputStream(input.length);
df.finish();
byte[] buff = new byte[1024];
while (!df.finished()) {
int count = df.deflate(buff);
baos.write(buff, 0, count);
}
baos.close();
byte[] output = baos.toByteArray();
return output;
}
public static String uncompress(byte[] input)
throws UnsupportedEncodingException, IOException,
DataFormatException {
Inflater ifl = new Inflater();
ifl.setInput(input);
ByteArrayOutputStream baos = new ByteArrayOutputStream(input.length);
byte[] buff = new byte[1024];
while (!ifl.finished()) {
int count = ifl.inflate(buff);
baos.write(buff, 0, count);
}
baos.close();
byte[] output = baos.toByteArray();
return new String(output);
}
我的测试工作如下(工作正常)
String text = "some text";
byte[] bytes = Compressor.compress(text);
assertEquals(Compressor.uncompress(bytes), text); // works
出于其他原因,为什么不呢,我想修改第一个方法以返回 String
而不是 byte[]。
所以我从compress
方法返回新的String(output)
并将我的测试修改为:
String text = "some text";
String compressedText = Compressor.compress(text);
assertEquals(Compressor.uncompress(compressedText.getBytes), text); //fails
此测试失败,并显示 java.util.zip.DataFormatException:错误的 header 检查
这是为什么呢?需要做什么才能使其发挥作用?
最佳答案
String(byte[])
构造函数是问题所在。您不能简单地获取任意字节,将它们转换为字符串,然后再转换回字节数组。 String
类根据所需的字符集对此byte
执行复杂的编码。如果给定的字节序列无法表示,例如在 Unicode 中,它将被丢弃或转换为其他内容。仅当这些字节确实表示某些String
(以某种编码方式)时,从字节到String
再返回到bytes
的转换才是无损的。
这是一个最简单的例子:
new String(new byte[]{-128}, "UTF-8").getBytes("UTF-8")
以上返回 -17, -65, -67
,而 127
输入返回完全相同的输出。
关于java - 字符串、byte[] 和压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11762975/