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 がダイレクトに欲しい...

使い方を間違えているのだろうか...