Decompression of GZIPInputStream did not work fine for compressed data longer than 532 bytes

I created compression and decompression using gZipInputStream in java It works fine for small amount of data, but if the length of the data after compression becomes larger than n 532 then my decompression does not work fine.

Thanks Bapita

+1


a source to share


3 answers


To repeat what others have said:

  • It often happens that str.length ()! = Str.getBytes (). length () . Many operating systems use variable length encoding (such as UTF-8, UTF-16, or Windows-949 ).
  • Use OutputStream.close to ensure that all data is written correctly.
  • Use the return value InputStream.read to find out how many bytes have been read. There is no guarantee that all data will be read in one go.
  • Be careful when using the String class for encoding / decoding.

Methods for compressing / decompressing strings



  private static byte[] compress(String str, Charset charset) {
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    try {
      OutputStream deflater = new GZIPOutputStream(buffer);
      deflater.write(str.getBytes(charset));
      deflater.close();
    } catch (IOException e) {
      throw new IllegalStateException(e);
    }
    return buffer.toByteArray();
  }

  private static String decompress(byte[] data,
      Charset charset) {
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    ByteArrayInputStream in = new ByteArrayInputStream(data);
    try {
      InputStream inflater = new GZIPInputStream(in);
      byte[] bbuf = new byte[256];
      while (true) {
        int r = inflater.read(bbuf);
        if (r < 0) {
          break;
        }
        buffer.write(bbuf, 0, r);
      }
    } catch (IOException e) {
      throw new IllegalStateException(e);
    }
    return new String(buffer.toByteArray(), charset);
  }

  public static void main(String[] args) throws IOException {
    StringBuilder sb = new StringBuilder();
    while (sb.length() < 10000) {
      sb.append("write the data here \u00A3");
    }
    String str = sb.toString();
    Charset utf8 = Charset.forName("UTF-8");
    byte[] compressed = compress(str, utf8);

    System.out.println("String len=" + str.length());
    System.out.println("Encoded len="
        + str.getBytes(utf8).length);
    System.out.println("Compressed len="
        + compressed.length);

    String decompressed = decompress(compressed, utf8);
    System.out.println(decompressed.equals(str));
  }

      

(Note that since these are streams in memory, I am not strict about how I open or close them.)

+5


a source


Looks like a char encoding / decoding problem to me. To write strings one should use Readers/Writers

, for example. String.getBytes()

... Using the designs String(new byte[])

are not .



You really need to use a loop to read and check the return value of the read bytes for everything to be read!

+2


a source


I suggest you use gCompress.close () not finish ();

I also suggest that you can't rely on str.length () long enough to read. There is a risk that the data may be longer and therefore the string will be truncated.

You are also ignoring the return value of read (). read () is guaranteed to only read () one byte and is unlikely to accurately read data from str.length () bytes of data, so you will likely have many trailing nul bytes \ 0. Instead, you can expect to read str.getBytes (). Length ()

+1


a source







All Articles