ストリームがJavaで圧縮されているかどうかを検出する最良の方法
-
05-07-2019 - |
質問
圧縮されたデータが含まれている java.io.InputStream
を見つける最良の方法は何ですか?
他のヒント
はじめに
すべての答えは5歳なので、今日何が起こっているのかを書き留める義務があります。ストリームの魔法のバイトを読むべきだと真剣に思っています!これは低レベルのコードです。一般的には避けてください。
単純な回答
mikuの書き込み:
ZipInputStreamを介してストリームを読み取ることができる場合、圧縮する必要があります。
はい、ただし ZipInputStream
の場合" readed canquote"は、 .getNextEntry()
の最初の呼び出しがnull以外の値を返すことを意味します。キャッチなどは例外ではありません。そのため、マジックバイトの解析の代わりに、次のことができます。
boolean isZipped = new ZipInputStream(yourInputStream).getNextEntry() != null;
これで完了です!
一般的な解凍の考え方
一般に、ストリームを使用するよりも[un] zipを使用してファイルを操作する方がはるかに便利であると思われました。いくつかの便利なライブラリがあり、さらにZipFileにはZipInputStreamよりも多くの機能があります。 zipファイルの処理については、次を参照してください。良いことJavaライブラリを使用してファイルをzip / unzipしますか。
コードサンプル
アプリケーションでストリームのみを使用する必要がありました。これが私が解凍用に書いたメソッドです:
import org.apache.commons.io.IOUtils;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public boolean unzip(InputStream inputStream, File outputFolder) throws IOException {
ZipInputStream zis = new ZipInputStream(inputStream);
ZipEntry entry;
boolean isEmpty = true;
while ((entry = zis.getNextEntry()) != null) {
isEmpty = false;
File newFile = new File(outputFolder, entry.getName());
if (newFile.getParentFile().mkdirs() && !entry.isDirectory()) {
FileOutputStream fos = new FileOutputStream(newFile);
IOUtils.copy(zis, fos);
IOUtils.closeQuietly(fos);
}
}
IOUtils.closeQuietly(zis);
return !isEmpty;
}
ストリームの最初の4バイトが、ZIPファイル内のすべてのファイルを処理するローカルファイルヘッダーを開始するローカルファイルヘッダー署名であることを確認できます< a href = "http://www.pkware.com/documents/casestudies/APPNOTE.TXT" rel = "noreferrer">仕様に記載されているとおり、 50 4B 03 04
。
これが機能することを示す小さなテストコード:
byte[] buffer = new byte[4];
try {
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("so.zip"));
ZipEntry ze = new ZipEntry("HelloWorld.txt");
zos.putNextEntry(ze);
zos.write("Hello world".getBytes());
zos.close();
FileInputStream is = new FileInputStream("so.zip");
is.read(buffer);
is.close();
}
catch(IOException e) {
e.printStackTrace();
}
for (byte b : buffer) {
System.out.printf("%H ",b);
}
この出力を送ってください:
50 4B 3 4
あまりエレガントではないが、信頼性が高い:
ZipInputStream
、圧縮する必要があります。
マジックナンバーを確認するのは適切な選択肢ではない可能性があります。
Docxファイルも同様のマジック番号50 4B 3 4を持っています