最近、ふとん圧縮袋の通販見ないねぇw
ZipOutputStreamを使って、フォルダを丸ごとZIPファイルに圧縮するサンプル
ZipOutputStreamを使って、フォルダを丸ごとZIPファイルに圧縮します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipCompressTest { private static final int BUFFER_SIZE = 4096; public static void main(String[] args) { String srcPath = "C:\\work\\in"; String destPath = "C:\\work\\out\\output.zip"; try { //ZIPファイルに圧縮 compressZip(srcPath, destPath); } catch (IOException e) { e.printStackTrace(); } } public static void compressZip(String srcPath, String destPath) throws IOException { System.out.println("圧縮対象フォルダ:"+srcPath); System.out.println("圧縮先ファイル:"+destPath); //圧縮先ファイルの出力ストリームを作成 try(FileOutputStream fos = new FileOutputStream(destPath); ZipOutputStream zos = new ZipOutputStream(fos);){ Path entryPath = Paths.get(srcPath); //フォルダ内のファイルとサブフォルダを再帰的にZIPに追加 compressEntry(entryPath, entryPath.getFileName().toString(), zos); } System.out.println("処理終了.."); } private static void compressEntry(Path targetPath, String parentDirName, ZipOutputStream zos) throws IOException { //フォルダ内のフォルダ、ファイルを取得 try (DirectoryStream<Path> ds = Files.newDirectoryStream(targetPath)) { for (Path filePath : ds) { if (Files.isDirectory(filePath)) { //フォルダの場合、再帰的に処置 compressEntry(filePath, parentDirName + "/" + filePath.getFileName(), zos); } else { //ファイルの場合、圧縮 System.out.println("-> 圧縮中.. " + parentDirName + "/" + filePath.getFileName().toString()); ZipEntry zipEntry = new ZipEntry(parentDirName + "/" + filePath.getFileName().toString()); zos.putNextEntry(zipEntry); try(FileInputStream fis = new FileInputStream(filePath.toFile()); BufferedInputStream bis = new BufferedInputStream(fis);){ byte[] buffer = new byte[BUFFER_SIZE]; int len = -1; while ((len = bis.read(buffer, 0, buffer.length)) != -1) { zos.write(buffer, 0, len); } } zos.closeEntry(); } } } } } |
実行結果
指定したファイル名でZIPファイルが作成されます。
1 2 3 4 5 6 7 | 圧縮対象フォルダ:C:\work\in 圧縮先ファイル:C:\work\out\output.zip -> 圧縮中.. in/a.txt -> 圧縮中.. in/hoge/b.txt -> 圧縮中.. in/hoge/かきくけこ.txt -> 圧縮中.. in/あいうえお.txt 処理終了.. |
サンプルの解説
ZIPファイルを作成するには、ZipOutputStreamを使います。
ZipEntryが内部に圧縮されるもの。つまり圧縮対象のファイルです。
このZipEntry単位で、ZipOutputStreamのputNextEntry、write、closeEntryを繰り返します。
ZipOutputStream#write付近の処理は、Files.readAllBytes()等を使って、一撃で書いてしまうと楽ではあるんですが、ファイルサイズが大きいとメモリ不足で死にますw
なので、今回は4KB単位に流す感じにしています。
処理の流れは単純で、compressEntryメソッドで再帰的に処理をしています。
フォルダであれば再帰処理。ファイルだったら圧縮です。
というわけで、今回作ったcompressEntryメソッドは、フォルダが渡ってくる前提になっているので、単品のファイル圧縮には対応していませんねぇw