Noah Koster
Noah Koster

Reputation: 175

Java zlib decompression error "unknown compression method"

i am in highschool and need to complete a project for my ap computer programming course. basically, my teacher went over zlib decompression and compression in java and told us to make a small java program that decompressed some compressed data. i would like to add that i am a minecraft addict and found out that chunks in minecraft are compressed in zlib, so i set out to decompress those chunks. anyway the code isnt working and i have to complete it by tuesday. what mistake am i making? all help would be greatly appreciated. code:

public static void read(String filein) throws IOException, DataFormatException{
    //Initialize
    ArrayList<Byte> bufflist = new ArrayList<Byte>();
    File file = new File(filein);
    RandomAccessFile mcr = new RandomAccessFile(file, "r");
    RandomAccessFile cache = new RandomAccessFile("cache", "rw");
    RandomAccessFile out = new RandomAccessFile("out", "rw");

    //read file
    int dataread = 0;
    mcr.seek(8192);
    while (dataread < file.length() - 8192){
        dataread = dataread + 1;
        byte b = mcr.readByte();
        bufflist.add(b);
    }
    mcr.close();
    //decode
    for (int y=0; y<bufflist.size()-1; y++){
        cache.write(bufflist.get(y));
    }
    InflaterInputStream infl = new InflaterInputStream(new FileInputStream("cache"), new Inflater());
    int data = infl.read();
    out.write(data);
}
public static void main(String[] args) throws IOException, DataFormatException
{
    read("r.1.1.mca");      
}

Upvotes: 2

Views: 3197

Answers (2)

JimmyB
JimmyB

Reputation: 12610

Just a note: While there are many tools using zlib for (de-)compression, the results are stored in a multitude of different (proprietary) file formats. - You need to know which format the compressed data was stored in to be able to decompress it, even when the compression algorithm matches.

So, are you sure that at offset 8192 of your input file a data stream follows which is in exactly the format zlib expects? - I would not assume it to be in a proprietary file format. Using plain zlib you will not even be able to decompress a common PKZIP (".zip") archive. Don't waste your time on this, but find some other data to play with.

You may want to try to first compress some known data via zlib, store it to a file or whatever and take a look at it if you desire. Then, take that file of compressed data, hand it to the zlib and see if you can have it decompressed into the original form. If you can do that you will already have learned a lot about how to use zlib.

For other tasks, like processing those ".zip" files, you may want to look into Java's API in the java.util.zip package.

Oh, and by the way: The "unknown compression method" result may be a bit misleading. This merely signals that zlib was unable to determine how to decompress the given data and this is more often than not caused by 'broken' input that, at least in the given form, cannot be processed by zlib in the first place.

As to your code:

Make sure you delete your output files before trying to write to them; writing to an existing file your way will append the data to the file's existing data instead of replacing the old bytes.

You should really close() your 'cache' file before trying to read from it through a new InputStream.

In your for loop y<bufflist.size()-1 should actually be y<bufflist.size().

You can spare all of that bufflist stuff: Simply replace bufflist.add(b); with cache.write(b);.

Upvotes: 3

Nick ODell
Nick ODell

Reputation: 25220

IIRC, in Anvil, each .mca file stores multiple "sections" which are individually compressed so that the entire chunk doesn't need to be recompressed whenever something is modified.

Check out the McRegion/Anvil converter here. It's a good starting point for figuring out how anvil files are packed.

Good luck with your project!

Upvotes: 2

Related Questions