ant.jar を使って tar を zip みたいに操作したかったんだけど
結局 tar コマンドを使うことになりましたよ,という話.
(※ tar でローカルに展開し,個々のファイルを FileInputStream として取得した)
zip の場合
以下のように,エントリ名から InputStream を取得できる.
final ZipEntry entry = zip.getEntry(name); return zip.getInputStream(entry);
tar の場合
ant.jar をクラスパスに指定し,org.apache.tools.tar パッケージを使用する.
getInputStream みたいなメソッドが見当たらなかったため,とりあえず,エントリ名から InputStream を取得するコードを書いてみたけど,あまりよくない.
(OutOfMemory しますよ)
InputStream findEntryInputStream(final String name) throws IOException { final TarInputStream tin = new TarInputStream( new GZIPInputStream( new FileInputStream(getSrc()))); // File getSrc() というメソッド try { TarEntry entry = null; while ((entry = tin.getNextEntry()) != null) { if (!name.equals(entry.getName())) { continue; } // name の Entry がみつかった // この書き方はよくない (OutOfMemory になる) return new ByteArrayInputStream(getByteArray(tin)); } return null; } finally { if (tin != null) { tin.close(); } } } byte[] getByteArray(final TarInputStream input) throws IOException { final ByteArrayOutputStream tmp = new ByteArrayOutputStream(); try { input.copyEntryContents(tmp); return tmp.toByteArray(); } finally { if (tmp != null) { tmp.close(); } } }
TarInputStream#copyEntryContents(OutputStream) を使えば Entry が読み込めるけど,巨大なファイル (数百 MB ) を扱う場合は,Entry の InputStream がダイレクトに欲しい...
使い方を間違えているのだろうか...