java GZIP解压字符串和字节转换
我的代码有问题:
private static String compress(String str)
{
String str1 = null;
ByteArrayOutputStream bos = null;
try
{
bos = new ByteArrayOutputStream();
BufferedOutputStream dest = null;
byte b[] = str.getBytes();
GZIPOutputStream gz = new GZIPOutputStream(bos,b.length);
gz.write(b,0,b.length);
bos.close();
gz.close();
}
catch(Exception e) {
System.out.println(e);
e.printStackTrace();
}
byte b1[] = bos.toByteArray();
return new String(b1);
}
private static String deCompress(String str)
{
String s1 = null;
try
{
byte b[] = str.getBytes();
InputStream bais = new ByteArrayInputStream(b);
GZIPInputStream gs = new GZIPInputStream(bais);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int numBytesRead = 0;
byte [] tempBytes = new byte[6000];
try
{
while ((numBytesRead = gs.read(tempBytes, 0, tempBytes.length)) != -1)
{
baos.write(tempBytes, 0, numBytesRead);
}
s1 = new String(baos.toByteArray());
s1= baos.toString();
}
catch(ZipException e)
{
e.printStackTrace();
}
}
catch(Exception e) {
e.printStackTrace();
}
return s1;
}
public String test() throws Exception
{
String str = "teststring";
String cmpr = compress(str);
String dcmpr = deCompress(cmpr);
}
这段代码将抛出java。木卫一。IOException:未知格式(幻数ef1f)
GZIPInputStream gs = new GZIPInputStream(bais);
结果表明,在转换字节new String (b1)
和byte b [] = str.getBytes ()
时,字节被“损坏”在行的输出端,我们已经有了更多的字节。如果您避免转换为字符串并使用字节处理行,那么一切都可以正常工作。对不起我的英语
public String unZip(String zipped) throws DataFormatException, IOException {
byte[] bytes = zipped.getBytes("WINDOWS-1251");
Inflater decompressed = new Inflater();
decompressed.setInput(bytes);
byte[] result = new byte[100];
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
while (decompressed.inflate(result) != 0)
buffer.write(result);
decompressed.end();
return new String(buffer.toByteArray(), charset);
}
我正在使用此函数解压缩服务器响应。谢谢你的帮助
# 1 楼答案
当你压缩数据时,你总是得到二进制数据。此数据无法转换为字符串,因为它不是有效的字符数据(在任何编码中)
所以你的压缩方法应该返回一个字节数组,你的解压缩方法应该把字节数组作为它的参数
此外,我建议在压缩之前将字符串转换为字节数组时,以及在将解压后的数据再次转换为字符串时,使用显式编码
# 2 楼答案
科多说得对,非常感谢你启发我。我试图解压一个字符串(从二进制数据转换而来)。我修改的是在http连接返回的输入流上直接使用InflateInputStream。(我的应用程序正在检索大量字符串)
# 3 楼答案
你有两个问题:
String(byte[])
构造函数将压缩结果的不透明二进制数据表示为字符串。该构造函数仅用于编码文本的数据。。。但这不是。你应该使用base64。有一个public domain base64 library使这很容易。(或者,根本不要将压缩数据转换为文本,只需返回字节数组即可。)李>从根本上说,您需要了解文本和二进制数据的不同之处——当您想要在两者之间进行转换时,您应该小心地进行转换。如果你想用字符串表示“非文本”二进制数据(即不是编码文本的直接结果的字节),你应该使用base64或hex之类的东西。当您想将字符串编码为二进制数据(例如,将一些文本写入磁盘)时,应仔细考虑使用哪种编码。如果另一个程序要读取你的数据,你需要计算出它期望的编码——如果你自己完全控制它,我通常会选择UTF-8
此外,代码中的异常处理也很差:
Exception
;捕捉更具体的异常