2013-10-10 7 views
3

У меня есть следующий код для сжатия и декомпрессии строки.GZIP ест новые строки

public static byte[] compress(String str) 
{ 
    try 
    { 
     ByteArrayOutputStream obj = new ByteArrayOutputStream(); 
     GZIPOutputStream gzip = new GZIPOutputStream(obj); 
     gzip.write(str.getBytes("UTF-8")); 
     gzip.close(); 
     return obj.toByteArray(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
    return null; 
} 

public static String decompress(byte[] bytes) 
{ 
    try 
    { 
     GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes)); 
     BufferedReader bf = new BufferedReader(new InputStreamReader(gis, "UTF-8")); 
     StringBuilder outStr = new StringBuilder(); 
     String line; 
     while ((line = bf.readLine()) != null) 
     { 
      outStr.append(line); 
     } 
     return outStr.toString(); 
    } 
    catch (IOException e) 
    { 
     return e.getMessage(); 
    } 
} 

сжать в массив байтов на окнах, а затем отправить массив байтов через сокет к Linux и разархивируйте его там. Однако при распаковке кажется, что все мои символы новой строки исчезли.
Так что я думал, что проблема связана с linux to windows. Однако я попытался написать простую программу на окнах, которая ее использует, и обнаружил, что строки новой строки по-прежнему отсутствуют.
Может ли кто-нибудь пролить свет на то, что вызывает его? Я не могу понять никаких объяснений.

ответ

4

Я думаю, что проблема здесь:

while ((line = bf.readLine()) != null) 
    { 
     outStr.append(line); 
    } 

readLine видеть это символ новой строки символ, но не включает его в возвращаемом значении для line

Проблема хуже, чем вы думаете, возможно.

readLine() получает все символы до, но не включая, новую строку (или несколько вариантов возвратов и символов перевода строки) ИЛИ конец файла. Таким образом, вы не знаете, имела ли последняя строка у вас новая линия в конце или нет.

Это не вопрос, и если да, то вы можете просто добавить это после другой Append:

outStr.append('\n'); 

Некоторые файлы могут в конечном итоге с дополнительной линией, заканчивающийся в конце файла.

Если это имеет значение, вам нужно будет использовать read(), а затем вывести все символы, которые вы получаете. В этом случае вы можете оказаться в печально известном «Что находится в конце строки?». проблема, с которой вы сталкиваетесь между Windows, Linux и MacOS, и тем, как они используют разные комбинации возвращаемых и новых строк для завершения строк.

+0

Вы были правы. 'read()' только что сработал, но в моем случае '.append (" \ n ")' работает, и я в порядке, если мне случится получить дополнительную строку новой строки, но пока этого не произошло. – Quillion

5

Это не GZIP, который «питается» новыми символами.

Именно этот код:

while ((line = bf.readLine()) != null) 
    { 
     outStr.append(line); 
    } 

readLine() метод считывает строку (вплоть до и включая последовательность терминации линии), а затем возвращает его без строки. Затем вы присоедините его к outStr ... без, заменив завершенную линию.

Но даже если вы заменили окончание строки, вы не можете гарантировать, что фактическаяпоследовательность завершения строки была использована ... если вы это сделаете.

Я рекомендую вам заменить вызовы readLine() на звонки read(); то есть считывать и затем накапливать данные по одному символу за раз. Он решает сразу две проблемы. Это может быть даже быстрее, потому что вы избегаете ненужных накладных расходов на сбор строк строк.

+0

Мне очень жаль, но Ли был первым.Кроме того, я пробовал использовать read() и, к сожалению, из-за разных os ', используя разные символы, когда я переношу данные из одного в другое через сокет, символ новой строки действительно съедается. Спасибо за помощь, хотя :) решение было правильным, и мне это очень понравилось. – Quillion

Смежные вопросы