2012-05-13 7 views
10

Mam kilka ciągów, które mają około 10K znaków każdy. Jest w nich mnóstwo powtórzeń. Są serializowane obiekty JSON. Chciałbym łatwo skompresować je do tablicy bajtów i rozpakować je z tablicy bajtów.Jak mogę łatwo kompresować i dekompresować ciągi do/z tablic bajtowych?

Jak mogę najłatwiej to zrobić? Szukam sposobów, aby można było wykonać następujące czynności:

String original = "....long string here with 10K characters..."; 
byte[] compressed = StringCompressor.compress(original); 
String decompressed = StringCompressor.decompress(compressed); 
assert(original.equals(decompressed); 
+1

Użyłbym InflatorInputStream/DeflatorOutputStream z ByteArrayInput/OutputStream. –

+2

Istnieje łatwa w użyciu klasa "zip" ... edit - tutaj http://docs.oracle.com/javase/6/docs/api/java/util/zip/package-summary. html i wydaje się używać wymienionych klas @peter. –

+2

Co powiesz na to? http://stackoverflow.com/questions/3649485/how-to-compress-a-string –

Odpowiedz

23

Można spróbować

enum StringCompressor { 
    ; 
    public static byte[] compress(String text) { 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     try { 
      OutputStream out = new DeflaterOutputStream(baos); 
      out.write(text.getBytes("UTF-8")); 
      out.close(); 
     } catch (IOException e) { 
      throw new AssertionError(e); 
     } 
     return baos.toByteArray(); 
    } 

    public static String decompress(byte[] bytes) { 
     InputStream in = new InflaterInputStream(new ByteArrayInputStream(bytes)); 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     try { 
      byte[] buffer = new byte[8192]; 
      int len; 
      while((len = in.read(buffer))>0) 
       baos.write(buffer, 0, len); 
      return new String(baos.toByteArray(), "UTF-8"); 
     } catch (IOException e) { 
      throw new AssertionError(e); 
     } 
    } 
} 
+2

Witam, dlaczego używasz tutaj słowa "wyliczanie" zamiast "klasy"? Czy to dowodzi racji? –

+6

Niektórzy ludzie lubią używać klas wyliczeniowych jako sposobu implementacji klas singletowych lub statycznych. Zalecane przez Joshua Blocha, pisarza Efektywnej Javy. –

+0

To znaczy, że nie dopuszczono żadnych przypadków tej klasy. –

2

odpowiedź Petera Lawrey można nieco poprawić za pomocą tego mniej skomplikowanego kodu dla funkcji dekompresji

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    try { 
     OutputStream out = new InflaterOutputStream(baos); 
     out.write(bytes); 
     out.close(); 
     return new String(baos.toByteArray(), "UTF-8"); 
    } catch (IOException e) { 
     throw new AssertionError(e); 
    } 
0

Zrobiłem bibliotekę, aby rozwiązać problem kompresji generycznych napisów (szczególnie krótkich). Próbuje skompresować ciąg za pomocą różnych algorytmów (zwykłe utf-8, kodowanie 5bit dla łacińskich liter, kodowanie huffman, gzip dla długich łańcuchów) i wybiera ten z najkrótszym wynikiem (w najgorszym przypadku wybierze 8 kodowania, dzięki czemu nigdy nie ryzykujesz utratą miejsca).

Mam nadzieję, że może to być przydatne, Oto link https://github.com/lithedream/lithestring

EDIT: zdałem sobie sprawę, że struny są zawsze „długa”, moje domyślne biblioteki na gzip dla tych rozmiarach, boję się, że nie można zrobić lepiej dla ciebie .