2

On server (C++), binary data is compressed using ZLib function:

compress2() 

and it's sent over to client (Java). On client side (Java), data should be decompressed using the following code snippet:

public static String unpack(byte[] packedBuffer) { InflaterInputStream inStream = new InflaterInputStream(new ByteArrayInputStream( packedBuffer); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); int readByte; try { while((readByte = inStream.read()) != -1) { outStream.write(readByte); } } catch(Exception e) { JMDCLog.logError(" unpacking buffer of size: " + packedBuffer.length); e.printStackTrace(); // ... the rest of the code follows } 

Problem is that when it tries to read in while loop it always throws:

java.util.zip.ZipException: invalid stored block lengths

Before I check for other possible causes can someone please tell me can I compress on one side with compress2 and decompress it on the other side using above code, so I can eliminate this as a problem? Also if someone has a possible clue about what might be wrong here (I know I didn't provide too much of of the code in here but projects are rather big.

Thanks.

6
  • Just found this, might be helfful: jcraft.com/jzlib Commented Mar 26, 2013 at 9:08
  • Have you validated that you're getting the correct data out at the client side? Is your packedBuffer the right size, for example? Commented Mar 26, 2013 at 9:18
  • @Jon Skeet Slightly as that is the legacy code of one big system and for start I just wanted to know if I can unpack something compressed with zlib using compress2, with the java code I posted above, so I can move on with investigation of where is the problem. Commented Mar 26, 2013 at 10:48
  • @passenger: But my point is that you shouldn't be trying to diagnose this just from one side. You should look at the results of compress2(), checking the length and the data itself against what you receive in the Java code. If you're receiving the wrong data, you've got no hope of receiving it properly. Commented Mar 26, 2013 at 10:48
  • @Jon Skeet Thanks for your effort. Yes, I do know that, and that's my next step, but as this is the most easily checked and I didn't have so much experience with this in Java, I just wanted to check first if correctly compressed block with compress2 on one side can be decompressed with Java function pasted above? Commented Mar 26, 2013 at 10:55

2 Answers 2

0

I think the problem is not with unpack method but in packedBuffer content. Unpack works fine

public static byte[] pack(String s) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); DeflaterOutputStream dout = new DeflaterOutputStream(out); dout.write(s.getBytes()); dout.close(); return out.toByteArray(); } public static void main(String[] args) throws Exception { byte[] a = pack("123"); String s = unpack(a); // calls your unpack System.out.println(s); } 

output

123 
Sign up to request clarification or add additional context in comments.

3 Comments

Please don't recommend using the platform default encoding like this - it's highly non-portable. When converting from a String to a byte array or vice versa, you should always specify the encoding.
Thanks for responding, but does it also mean, that what is compressed in some C++ code with ZLib (using compress2 function) should be able to be decompressed with my Java unpack function?
java.util.zip is based on ZLIB compression library (native dll) and I think that it is compatible with C++ Zlib. But if you can decompress packedBuffer with C++ then it is compressed in a different format. But I am sure there is a C++ - Java compatible format
0
public static String unpack(byte[] packedBuffer) { try (GZipInputStream inStream = new GZipInputStream( new ByteArrayInputStream(packedBuffer)); ByteArrayOutputStream outStream = new ByteArrayOutputStream()) { inStream.transferTo(outStream); //... return outStream.toString(StandardCharsets.UTF_8); } catch(Exception e) { JMDCLog.logError(" unpacking buffer of size: " + packedBuffer.length); e.printStackTrace(); throw new IllegalArgumentException(e); } } 

ZLib is the zip format, hence a GZipInputStream is fine. A you seem to expect the bytes to represent text, hence be in some encoding, add that encoding, Charset, to the conversion to String (which always holds Unicode). Note, UTF-8 is the encoding of the bytes. In your case it might be an other encoding.

The ugly try-with-resources syntax closes the streams even on exception or here the return.

I rethrowed a RuntimeException as it seems dangerous to do something with no result.

3 Comments

What? The zlib format is not the zip format, and the gzip format is not the zlib format. Those are three different things.
@MarkAdler zlib is definitely more, but if DEFLATE/INFLATE fails, this would seem worth a try. But you seem mere experienced w.r.t. to the zlib aspects and especially compress2. I will wait a bit.
The zlib library is more. The zlib format is a specific thing.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.