2

私は高校生で、ap コンピューター プログラミング コースのプロジェクトを完了する必要があります。基本的に、私の先生は Java での zlib 解凍と圧縮について説明し、圧縮されたデータを解凍する小さな Java プログラムを作成するように言いました。私はマインクラフトの常習者であり、マインクラフトのチャンクがzlibで圧縮されていることを発見したので、それらのチャンクを解凍することに着手したことを付け加えたい. とにかくコードが機能しないので、火曜日までに完成させなければなりません。私はどんな間違いをしていますか?すべての助けをいただければ幸いです。コード:

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");      
}
4

2 に答える 2

3

注:(解凍)圧縮にzlibを使用するツールは多数ありますが、結果は多数の異なる(独自の)ファイル形式で保存されます。-圧縮アルゴリズムが一致する場合でも、データを解凍できるようにするには、圧縮データがどの形式で保存されているかを知る必要があります。

それで、入力ファイルのオフセット8192で、zlibが期待する形式のデータストリームが続くことを確認しますか?-私はそれがプロプライエタリファイル形式であるとは思いません。プレーンなzlibを使用すると、一般的なPKZIP( ".zip")アーカイブを解凍することもできなくなります。これに時間を無駄にしないでください。ただし、他のデータを見つけて遊んでください。

最初にzlibを介していくつかの既知のデータを圧縮し、それをファイルなどに保存して、必要に応じて確認することをお勧めします。次に、その圧縮データのファイルを取得し、それをzlibに渡して、元の形式に解凍できるかどうかを確認します。それができれば、zlibの使い方について多くのことをすでに学んでいるはずです。

java.util.zipこれらの「.zip」ファイルの処理などの他のタスクについては、パッケージ内のJavaのAPIを調べることをお勧めします。

ちなみに、「不明な圧縮方法」の結果は少し誤解を招く可能性があります。これは、zlibが指定されたデータを解凍する方法を判別できなかったことを示しているだけであり、これは多くの場合、少なくとも指定された形式では、そもそもzlibで処理できない「壊れた」入力が原因です。

あなたのコードに関して:

出力ファイルに書き込もうとする前に、必ず出力ファイルを削除してください。既存のファイルに書き込むと、古いバイトを置き換える代わりに、ファイルの既存のデータにデータが追加されます。

close()新しいを介してファイルから読み取ろうとする前に、実際には「キャッシュ」ファイルを作成する必要がありますInputStream

forループ内y<bufflist.size()-1には実際にはが必要ですy<bufflist.size()

あなたはそのすべてのものを惜しまないことができますbufflist:単に。に置き換えbufflist.add(b);cache.write(b);ください。

于 2012-11-11T17:50:16.023 に答える
2

IIRC の Anvil では、各 .mca ファイルに個別に圧縮された複数の「セクション」が格納されるため、何かが変更されるたびにチャンク全体を再圧縮する必要はありません。

ここでMcRegion/Anvil コンバーターをチェックしてください。これは、anvil ファイルがどのようにパックされているかを理解するための良い出発点です。

あなたのプロジェクトで頑張ってください!

于 2012-11-11T19:09:45.540 に答える