Linux標準の圧縮形式、tar.gz。業務で、Javaの小物を作ることになったのでメモ。
tar.gzの仕組み
2段階に圧縮している。
ファイル | (複数ファイルをTARで1つのバイナリに連結) ↓ TARファイル | (1ファイルをGZip圧縮) ↓ TAR.GZファイル
Javaのライブラリ
今回は、Java標準のGZIPInputStream
、Apache Commons CompressのTarArchiveInputStream
を使った。
File outDir = new File("/outdir"); File gzipFile = new File("sample.tar.gz"); try (FileInputStream fis = new FileInputStream(gzipFile)) { try (GZIPInputStream gis = new GZIPInputStream(fis)) { try (TarArchiveInputStream tis = new TarArchiveInputStream(gis)) { for (AchiveEntry entry = tis.getNextEntry(); entry != null; entry = tis.getNextEntry()) { if (entry.isDirectory()) { File newDir = new File(outDir, entry.getName()); if (!newDir.mkdirs()) { throw new IOException("directory " + newDir.getAbsolutePath() + " cannot create.'); } } else { File newfile = new File(outDir, entry.getName()); File parentDir = newfile.getParent(); if (!parentDir.mkdirs()) { throw new IOException("directory " + parentDir.getAbsolutePath() + " cannot create.'); } try (FileOutputStream fos = new FileOutputStream(newfile)) { IOUtils.copy(tis, fos); // Apache common-io } } } } } }
なんだこのネスト。やってることは単純なんだけど。
TarAchiveInputStreamのAPIがやや癖があって、getNextEntryすると、TarArhiveInputStreamのファイルポインタが進む。
また、GZIPInputStreamには作業バッファ長が与えられる。だいたい、デフォルトの8196で十分だが、CPUリソースが余りに余るようであれば増やしてもよいかもしれない。