0

私は Java にまったく慣れていないので、Java で小さなプロジェクトを実行して学習することにしました。zlib を使用して文字列を圧縮し、ファイルに書き込む必要があります。ただし、ファイルのサイズが大きすぎることが判明しました。コード例は次のとおりです。

String input = "yasar\0yasar"; // test input. Input will have null character in it.
byte[] compressed = new byte[100];  // hold compressed content

Deflater compresser = new Deflater();
compresser.setInput(input.getBytes());
compresser.finish();
compresser.deflate(compressed);
File test_file = new File(System.getProperty("user.dir"), "test_file");
try {
    if (!test_file.exists()) {
        test_file.createNewFile();
    }
    try (FileOutputStream fos = new FileOutputStream(test_file)) {
        fos.write(compressed);
    }
} catch (IOException e) {
    e.printStackTrace();
}

これは 1 キロバイトのファイルを書き込みますが、ファイルは最大で 11 バイトでなければなりません (ここでは内容が 11 バイトであるため)。問題は、100バイトに圧縮されたバイト配列を初期化する方法にあると思いますが、圧縮されたデータが事前にどのくらいの大きさになるかわかりません。ここで何が間違っていますか?どうすれば修正できますか?

4

2 に答える 2

1

配列全体を書きたくない場合は、Deflater使用によって埋められた部分だけを書きます。OutputStream#write(byte[] array, int offset, int lenght)

おおむね

String input = "yasar\0yasar"; // test input. Input will have null character in it.
byte[] compressed = new byte[100];  // hold compressed content

Deflater compresser = new Deflater();
compresser.setInput(input.getBytes());
compresser.finish();
int length = compresser.deflate(compressed);
File test_file = new File(System.getProperty("user.dir"), "test_file");
try {
    if (!test_file.exists()) {
        test_file.createNewFile();
    }
    try (FileOutputStream fos = new FileOutputStream(test_file)) {
        fos.write(compressed, 0, length); // starting at 0th byte - lenght(-1)
    }
} catch (IOException e) {
    e.printStackTrace();
}

1kBそこに表示されるものは丸められているように見えるか(以前に100バイトを書いた)、または少なくとも1ブロックの大きさのファイルシステム上のサイズを参照しているため(4kb IIRCである必要があります) 、Windowsではおそらくまだ表示されます。ファイルを右クリックし、プロパティでサイズを確認すると、実際のサイズが表示されます。


サイズが事前にわからない場合はDeflater、 を使用せず、任意の長さのデータを圧縮して書き込むDeflaterOutputStreamを使用してください。

try (OutputStream out = new DeflaterOutputStream(new FileOutputStream(test_file))) {
    out.write("hello!".getBytes());
}

上記の例では、デフレートにデフォルト値を使用しますがDeflater、コンストラクターで構成済みを渡しDeflaterOutputStreamて動作を変更することができます。

于 2013-08-07T10:26:49.407 に答える