最近、ふとん圧縮袋の通販見ないねぇ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











