2016-07-12 70 views
0

我有Base64字符串。我试图解码它,然后解压缩它。我使用的减压无法转换Base64字符串并正确解压缩

String textToDecode = "H4sIAAAAAAAAAAEgAN//0JTQtdGC0LDQu9C40LfQuNGA0L7QstCw0L3QvdGL0LmRCuyiIAAAAA==\n"; 
byte[] data = Base64.decode(textToDecode, Base64.DEFAULT); 
String result = GzipUtil.decompress(data); 

代码:

public static String decompress(byte[] compressed) throws IOException { 
    final int BUFFER_SIZE = 32; 
    ByteArrayInputStream is = new ByteArrayInputStream(compressed); 
    GZIPInputStream gis = new GZIPInputStream(is, BUFFER_SIZE); 
    StringBuilder string = new StringBuilder(); 
    byte[] data = new byte[BUFFER_SIZE]; 
    int bytesRead; 
    while ((bytesRead = gis.read(data)) != -1) { 
     string.append(new String(data, 0, bytesRead)); 
    } 
    gis.close(); 
    is.close(); 
    return string.toString(); 
} 

我应该得到这个字符串:

Детализированный 

它Insteam,我得到这个字符串以问号符号:

Детализирован��ый 

什t是我的错误?以及如何解决它?

回答

0

一个问题是,从字节转换为字符串(在内部的Unicode) 编码时没有给出。对于像UTF-8这样的多字节编码,无法获取固定数量的字节(如32),然后在最后有一个有效的序列。

你经历显然是一个半序列的损失。因此编码可能是UTF-8。

final int BUFFER_SIZE = 32; 
ByteArrayInputStream is = new ByteArrayInputStream(compressed); 
GZIPInputStream gis = new GZIPInputStream(is, BUFFER_SIZE); 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
byte[] data = new byte[BUFFER_SIZE]; 
int bytesRead; 
while ((bytesRead = gis.read(data)) != -1) { 
    baos.write(data, 0, bytesRead); 
} 
gis.close(); 
return baos.toString("UTF-8"); // Or "Windows-1251" ... 

上面的内容消除了缓冲区边界问题,并指定了编码,因此相同的代码在不同的计算机上运行。

和思想。

  • new String(bytes, encoding)
  • string.getBytes(encoding)
0

这是可能的,问题就在这里:

string.append(new String(data, 0, bytesRead)) 

您使用的是默认的字符编码解码字节到Java String类型。如果(当前)默认编码不同于将原始字符编码为字节时使用的编码(在压缩之前等),那么您可能会得到不正确解码的字节。然后解码器将用解码器的替换字符替换它们;即默认为'\uFFFD'

如果这是问题,那么解决方法是找出正确的字符编码是什么,并使用String(byte[], int, int, Charset)来创建String

+0

我确定它是由“UTF-8”编码的。按照你的建议,我尝试了这个'string.append(new String(data,0,bytesRead,“UTF-8”));'但它没有帮助。 –

+0

我建议你在压缩/ base64之前和base64 /解压缩之前逐字节比较字节。和长度。另外,问问你自己是否应该在那里换行。 –

0

如果用流只有工作,你能避免编码的问题,这几行代码应该做的工作做好

public static String decompress(byte[] compressed) throws IOException { 
     try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) { 
      try (GZIPInputStream gis = new GZIPInputStream(
        new ByteArrayInputStream(compressed))) { 
       org.apache.commons.compress.utils.IOUtils.copy(gis, bos); 
      } 
      return bos.toString(); 
     } 
    }