Reputation: 13
I try to program (and understand) compression/decompression. I have a file which is compressed with zlib and I thought that I found the solution to decompress my file:
import java.util.Scanner;
import java.util.zip.*;
import java.io.*;
public class ZLibCompression
{
public static void main(String args[])throws IOException, DataFormatException {
File compressed = new File("./MyFile.hlb");
decompress(compressed, new File("./MyFile.txt"));
}
public static void decompress(File compressed, File raw)
throws IOException
{
try (InputStream inputStream = new InflaterInputStream(new FileInputStream(compressed));
OutputStream outputStream = new FileOutputStream(raw))
{
copy(inputStream, outputStream);
}
}
private static void copy(InputStream inputStream, OutputStream outputStream)
throws IOException
{
byte[] buffer = new byte[1000];
int length;
while ((length = inputStream.read(buffer)) > 0)
{
outputStream.write(buffer, 0, length);
}
}
}
But I get the following error stack trace:
Exception in thread "main" java.util.zip.ZipException: incorrect header check
at java.base/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:164)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:106)
at ZLibCompression.copy(ZLibCompression.java:46)
at ZLibCompression.decompress(ZLibCompression.java:20)
at ZLibCompression.main(ZLibCompression.java:11)
Then I checked the header of my file and it says:
{
"compression" : {
"crc32" : 2575274738,
"decompressed_size" : 9020404,
"type" : "zlib"
},
"encoded_data" : "eNrsvV2Xm0i
What is my error? I found a Python script that works fine with the same file:
#!/usr/bin/env python
import sys
import os
import json
import base64
import zlib
SETLIST_OR_BUNDLE = "MyFile.hlb"
infile = open(SETLIST_OR_BUNDLE)
data = json.load(infile)
infile.close()
keys = list(data.keys())
if 'encoded_data' in keys:
unz = zlib.decompress(base64.b64decode(data['encoded_data']))
setlist_or_bundle = json.loads(unz)
keys = list(setlist_or_bundle.keys())
if 'setlists' in keys:
setlists = setlist_or_bundle['setlists']
elif 'presets' in keys:
setlists = [setlist_or_bundle]
for setlist in setlists:
keys = list(setlist.keys())
if 'meta' in keys:
print()
print("SETLIST: %s" % (setlist['meta']['name']))
presets = setlist['presets']
#print json.dumps(presets, indent=4)
for preset in presets:
if 'meta' in list(preset.keys()):
meta = preset['meta']
preset_name = meta['name']
print(" ", preset_name)
I think it has something to do with the base64 part and I found a similar question where someone mentioned "you have to decode the Base64 string into a byte array first" - OK fine - Can anyone explain or give me a link to a tutorial? All I need is the same functionality in Java like the Python script above has - And of course I want to learn something...
Upvotes: 1
Views: 1419
Reputation: 407
First of all, it looks like your file is not compressed as a whole. Instead, it is a JSON-String containing the actual compressed data as encoded_data
. You also need to unwrap the JSON-String then. The easiest way to deal with JSON encrypted data is by using a library. Check this post for some comparisons of different libraries.
Next, as you can see in your python code, the encoded data gets decoded from Base64 before passed through the ZLIB-Decompressor (zlib.decompress(base64.b64decode(data))
)
The java equivalent to un-Base64 a String would be:
Base64.getDecoder().decode(string);
Upvotes: 2