2016-07-12 2 views
0

У меня есть Base64 String. Я пытаюсь его расшифровать, а затем распаковать.Невозможно преобразовать Base64 String и правильно установить его

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 его, я получаю эту строку с вопросительным знаком символов:

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

Wha Это моя ошибка? И как его решить?

ответ

0

Одна из проблем заключается в том, что при преобразовании из байтов в String (внутренне 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 (новый 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(); 
     } 
    }