2012-05-13 27 views
10

Tôi có một số chuỗi có kích thước khoảng 10K ký tự. Có rất nhiều sự lặp lại trong chúng. Chúng là các đối tượng JSON được tuần tự hóa. Tôi muốn dễ dàng nén chúng vào một mảng byte, và giải nén chúng khỏi một mảng byte.Làm thế nào tôi có thể dễ dàng nén và giải nén các chuỗi đến/từ mảng byte?

Tôi có thể dễ dàng thực hiện việc này bằng cách nào? Tôi đang tìm phương pháp để tôi có thể làm như sau:

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

Tôi sẽ sử dụng InflatorInputStream/DeflatorOutputStream với ByteArrayInput/OutputStream. –

+2

Có một lớp 'zip' dễ sử dụng ở đó ... chỉnh sửa - nó ở đây http://docs.oracle.com/javase/6/docs/api/java/util/zip/package-summary. html và dường như sử dụng các lớp @peter được đề cập. –

+2

Làm thế nào về điều này? http://stackoverflow.com/questions/3649485/how-to-compress-a-string –

Trả lời

23

Bạn có thể thử

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

Xin chào, tại sao bạn sử dụng 'enum' thay vì' lớp' ở đây? Là nó để chứng minh một điểm? –

+6

Một số người thích sử dụng các lớp enum như một cách để thực hiện các lớp đơn hoặc các lớp tĩnh. Được đề xuất bởi Joshua Bloch, nhà văn của Java hiệu quả. –

+0

Nó để nói rằng không có trường hợp nào của lớp này được cho phép. –

2

câu trả lời Peter Lawrey có thể được cải thiện một chút sử dụng mã ít phức tạp này cho chức năng giải nén

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

Tôi đã thực hiện một thư viện để giải quyết vấn đề nén các chuỗi chung (đặc biệt là các chuỗi ngắn). Nó cố gắng nén chuỗi bằng cách sử dụng các thuật toán khác nhau (đồng bằng utf-8, mã hóa 5 bit cho chữ cái latin, mã hóa huffman, gzip cho chuỗi dài) và chọn chuỗi có kết quả ngắn nhất (trong trường hợp xấu nhất, nó sẽ chọn utf- 8 mã hóa, để bạn không bao giờ có nguy cơ mất không gian).

tôi hy vọng nó có thể hữu ích, đây là liên kết https://github.com/lithedream/lithestring

EDIT: Tôi nhận ra rằng Strings của bạn luôn luôn "dài", giá trị mặc định thư viện của tôi trên gzip đối với những kích thước, tôi sợ tôi không thể làm tốt hơn cho bạn .

Các vấn đề liên quan