JarファイルのI/Oについて
javaでJarファイルのI/Oをするには、java.util.jarパッケージ配下のクラス郡を使う。
読み取り
File file = new File("hoge.jar"); JarFile jarFile = new JarFile(file); JarEntry jarEntry = jarFile.getJarEntry("entryname"); InputStream in = jarFile.getInputStream(jarEntry);
書き込み
書き込みには、JarOutputStreamを使用する。
File file = new File("hoge.jar"); JarOutputStream out = new JarOutputStream(new FileOutputStream(file));
複数のファイルを一つのJarファイルに格納したい場合は、JarOutputStream#putNextEntry()を使用する。
File file = new File("hoge.jar"); // ストリームを開く。 JarOutputStream out = new JarOutputStream(new FileOutputStream(file)); // 最初のエントリを書く。 JarEntry jarEntry_01 = new JarEntry("jarEntry_01"); out.putNextEntry(jarEntry_01); out.write("これはjarEntry_01".getBytes()); out.closeEntry(); // 2番目のエントリを書く。 JarEntry jarEntry_02 = new JarEntry("jarEntry_02"); out.putNextEntry(jarEntry_02); out.write("これはjarEntry_02".getBytes()); out.closeEntry(); // ストリームを閉じる。 out.close();
最初のエントリを書き込んだ後に、closeEntry()を呼び出しているが、
2回目のputNextEntry()呼び出し時に、内部でcloseEntry()を呼び出しているので、もしかしたら明示的にcloseEntry()を呼び出す必要は無いかもしれない。
上記コードを実行すると、hoge.jarが作成される。
作成されたhoge.jarを、jarコマンドを使用して中を見てみると、以下のような感じになる。
>jar tvf hoge.jar 17 Thu Sep 03 03:28:52 JST 2009 jarEntry_01 17 Thu Sep 03 03:28:52 JST 2009 jarEntry_02
Jarファイルのフォーマットは、通常のZipファイルのフォーマットとほぼ同じなので、絵で表すと↓みたいな感じになっている。
ファイルの末尾に、ファイルヘッダ情報を持っていて、そこに、各エントリの開始位置が記載されている。
なので、JarEntry#close()を呼び出した時に、今まで書き込んだ各JarEntryの情報が書き込まれる。
作成されたhoge.jarを、バイナリエディタで見てみると、以下のような感じになる。