Javaの標準APIでZipの展開(解凍)を展開先を指定して行う
前回、
⇧ Javaの標準APIでZip圧縮を試してみましたが(ライブラリZip4jというものも試してます)、Javaの標準APIによるZipの展開(解凍)を試していなかったので試してみようと。
ネットの情報を漁ったところ、先人が情報発信してくれておりました、ありがたや。
⇧ 上記サイト様が情報を公開してくださっているので、利用させていただきました。
前回のソースコードを修正。
Javaの標準APIとライブラリZip4jがバッティングしてしまうので、クラスを分けました。
■/test-zip/src/main/java/com/example/demo/util/ZipStandardUtil.java
package com.example.demo.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.OpenOption; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; /** * Java標準のAPIのみでZip処理 */ public class ZipStandardUtil { /** * Zip圧縮 * @param zipName Zipファイル名 * @param targetRootPath Zip対象のルートパス * @param option * @param encoding 文字コード * @return */ public static boolean zip(String zipName, String targetRootPath, OpenOption option, Charset encoding) { Path pathZipInput = Paths.get(targetRootPath); Path pathZipOutput = Paths.get(zipName); //int countZip = 0; try (OutputStream os = Files.newOutputStream(pathZipOutput, option); ZipOutputStream zos = new ZipOutputStream(os, encoding)) { //for (String targetPathStr: targetPathList) { if (Files.isDirectory(pathZipInput)) { directoryZip(pathZipInput.getNameCount(), pathZipInput, zos); } else { // 新しいファイル名を指定し、zip中に設定 ZipEntry zipEntry = new ZipEntry(pathZipInput.getFileName().toString()); zos.putNextEntry(zipEntry); byte[] bytes = Files.readAllBytes(pathZipInput); zos.write(bytes); } zos.closeEntry(); //} } catch (IOException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } return true; } private static void directoryZip(int rootCount, Path path, ZipOutputStream zip) throws IOException { Files.list(path).forEach( p -> { try { var pathName = p.subpath(rootCount, p.getNameCount()); if (Files.isDirectory(p)) { zip.putNextEntry(new ZipEntry(pathName + "/")); directoryZip(rootCount, p, zip); } else { zip.putNextEntry(new ZipEntry(pathName.toString())); zip.write(Files.readAllBytes(p)); } } catch (IOException e) { throw new RuntimeException("ファイル操作で問題が発生しました。", e); } }); } /** * Zip展開(解凍) * @param zipFilePath */ public static void unzip(Path zipFilePath, String decompressDir) { try { File zipFile = new File(zipFilePath.toString()); ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile)); ZipEntry entry = null; while ((entry = zis.getNextEntry()) != null) { if (entry.isDirectory()) { new File(entry.getName()).mkdirs(); } else { File parent = new File(entry.getName()).getParentFile(); if (parent != null) { parent.mkdirs(); } FileOutputStream out = new FileOutputStream(entry.getName()); byte[] buf = new byte[1024]; int size = 0; while ((size = zis.read(buf)) != -1) { out.write(buf, 0, size); } out.close(); } zis.closeEntry(); } zis.close(); } catch (FileNotFoundException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } catch (IOException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } } public static boolean unzip(String zipFileFullPath, String unzipPath) { File baseFile = new File(zipFileFullPath); File baseDir = new File(baseFile.getParent(), baseFile.getName().substring(0, baseFile.getName().lastIndexOf("."))); if (!baseDir.mkdir()) System.out.println("Couldn't create directory because directory with the same name exists.: " + baseDir); ZipFile zipFile = null; try { // ZIPファイルオブジェクト作成 zipFile = new ZipFile(zipFileFullPath); // ZIPファイル内のファイルを列挙 Enumeration<? extends ZipEntry> enumZip = zipFile.entries(); // ZIPファイル内の全てのファイルを展開 while (enumZip.hasMoreElements()) { // ZIP内のエントリを取得 ZipEntry zipEntry = (java.util.zip.ZipEntry) enumZip.nextElement(); //出力ファイル取得 File unzipFile = new File(unzipPath); File outFile = new File(unzipFile.getAbsolutePath() + "/" + baseDir.getName(), zipEntry.getName()); if (zipEntry.isDirectory()) outFile.mkdir(); else { // 圧縮ファイル入力ストリーム作成 BufferedInputStream in = new BufferedInputStream(zipFile.getInputStream(zipEntry)); // 親ディレクトリがない場合、ディレクトリ作成 if (!outFile.getParentFile().exists()) outFile.getParentFile().mkdirs(); // 出力オブジェクト取得 BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outFile)); // 読み込みバッファ作成 byte[] buffer = new byte[1024]; // 解凍ファイル出力 int readSize = 0; while ((readSize = in.read(buffer)) != -1) { out.write(buffer, 0, readSize); } // クローズ try { out.close(); } catch (Exception e) { } try { in.close(); } catch (Exception e) { } } } // 解凍処理成功 return true; } catch (Exception e) { // エラーログ出力 System.out.println(e.toString()); // 解凍処理失敗 return false; } finally { if (zipFile != null) try { zipFile.close(); } catch (Exception e) { } } } }
■/test-zip/src/main/java/com/example/demo/util/ZipUtil.java
package com.example.demo.util; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import net.lingala.zip4j.ZipFile; import net.lingala.zip4j.exception.ZipException; /** * ライブラリZip4jを利用したZip処理 */ public class ZipUtil { /** * ライブラリZip4jで圧縮 * @param zipFilePath Zip圧縮後のファイルパス * @param compressDir Zip圧縮対象の起点ディレクトリ */ public static void zip(String zipFilePath, String compressDir ) { try { ZipFile zipFile = new ZipFile(zipFilePath); zipFile.addFolder(new File(compressDir)); zipFile.close(); } catch (ZipException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } catch (IOException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } } /** * ライブラリZip4jで圧縮 * @param zipFilePath * @param targetPath */ public static void zip(String zipFilePath, Path targetPath) { try { ZipFile zipFile = new ZipFile(zipFilePath); Files.list(targetPath).forEach(path -> { try { zipFile.addFolder(path.toFile()); } catch (ZipException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } }); zipFile.close(); } catch (IOException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } } /** * ライブラリZip4jで展開(解凍) * @param zipFilePath Zip圧縮後のファイルパス * @param decompressDir 展開(解凍)先のディレクトリパス */ public static void unzip(String zipFilePath, String decompressDir ) { try { ZipFile zipFile = new ZipFile(zipFilePath); zipFile.extractAll(decompressDir); zipFile.close(); } catch (ZipException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } catch (IOException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } } }
■/test-zip/src/test/java/com/example/demo/util/TestZipUtil.java
package com.example.demo.util; import java.nio.charset.StandardCharsets; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest public class TestZipUtil { // @Autowired // private ZipUtil zipUtil; /** * Javaの標準APIのZip処理
* Zip圧縮の確認 */ @Test public void test01() { // Zip圧縮対象の起点のディレクトリ String zipInput= "C:\\Eclipse-2023-06\\workspace\\test-zip\\target"; // Zip圧縮後のファイル名 String zipName = "C:\\Eclipse-2023-06\\workspace\\test-zip\\output\\office.zip"; // Zip圧縮処理 ZipStandardUtil.zip(zipName, zipInput, StandardOpenOption.CREATE, StandardCharsets.UTF_8); } /** * ライブラリZip4jを利用したZip処理
* Zip展開(解凍)の確認 */ @Test public void test02 () { // Zip圧縮後のファイル名 String zipName = "C:\\Eclipse-2023-06\\workspace\\test-zip\\output\\office.zip"; // Zip圧縮対象の起点のディレクトリ String zipDecompressDir= "C:\\Eclipse-2023-06\\workspace\\test-zip\\output"; ZipUtil.unzip(zipName, zipDecompressDir); } /** * ライブラリZip4jを利用したZip処理
* Zip圧縮の確認 */ @Test public void test03 () { // Zip圧縮対象の起点のディレクトリ String zipInput= "C:\\Eclipse-2023-06\\workspace\\test-zip\\target"; // Zip圧縮後のファイル名 String zipName = "C:\\Eclipse-2023-06\\workspace\\test-zip\\output\\zip4j-office.zip"; ZipUtil.zip(zipName, zipInput); } /** * ライブラリZip4jを利用したZip処理
* Zip展開(解凍)の確認 */ @Test public void test04 () { // Zip圧縮後のファイル名 String zipName = "C:\\Eclipse-2023-06\\workspace\\test-zip\\output\\zip4j-office.zip"; // Zip圧縮対象の起点のディレクトリ String zipDecompressDir= "C:\\Eclipse-2023-06\\workspace\\test-zip\\output"; ZipUtil.unzip(zipName, zipDecompressDir); } /** * ライブラリZip4jを利用したZip処理
* Zip圧縮の確認 */ @Test public void test05 () { // Zip圧縮対象の起点のディレクトリ String zipInput= "C:\\Eclipse-2023-06\\workspace\\test-zip\\target"; // Zip圧縮後のファイル名 String zipName = "C:\\Eclipse-2023-06\\workspace\\test-zip\\output\\test05_zip4j-office.zip"; ZipUtil.zip(zipName, Paths.get(zipInput)); } /** * ライブラリZip4jを利用したZip処理
* Zip展開(解凍)の確認 */ @Test public void test06 () { // Zip圧縮後のファイル名 String zipName = "C:\\Eclipse-2023-06\\workspace\\test-zip\\output\\test05_zip4j-office.zip"; // Zip圧縮対象の起点のディレクトリ String zipDecompressDir= "C:\\Eclipse-2023-06\\workspace\\test-zip\\output"; ZipUtil.unzip(zipName, zipDecompressDir); } /** * Javaの標準APIのZip処理
* Zip展開(解凍)の確認 */ @Test public void test07 () { // Zip圧縮後のファイル名 String zipName = "C:\\Eclipse-2023-06\\workspace\\test-zip\\output\\test05_zip4j-office.zip"; // Zip展開(解凍)先 String unzipDir = "C:\\Eclipse-2023-06\\workspace\\test-zip\\output"; ZipUtil.unzip(zipName, unzipDir); } }
⇧ で、test07を実行すると、
指定した展開先に展開(解凍)されました。
ライブラリZip4jで、展開先(解凍)の指定ができたりするのであれば、ライブラリの力に頼りたいのだが...
毎度モヤモヤ感が半端ない…
今回はこのへんで。