1. 程式人生 > 其它 >解壓一個目錄包括子目錄中的所有 zip 檔案

解壓一個目錄包括子目錄中的所有 zip 檔案

技術標籤:JavaScriptjava多執行緒zip

解壓一個目錄包括子目錄中的所有 zip 檔案

package unzip;

import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * @author jeffrey
 * @ClassName: UnZip
 * @Description: 為偷懶而生,解壓一個目錄包括子目錄中的所有 zip 檔案
 * @date: 2021/1/9 12:38 上午
 * @version:
 * @since JDK 1.8
 */
public class UnZip { /** * 用於存放於 zip 檔案的安全佇列 */ public final static ConcurrentLinkedQueue<File> ZIP_QUEUE = new ConcurrentLinkedQueue<>(); /** * 如 t1 不存活並 zipQueue 為空則修改為 true */ public static boolean isFlag = false; /** * 輸入流 */ private
static final Scanner SCANNER = new Scanner(System.in); /** * 提供一個工作路徑 */ private static String workPath; /** * 在解壓完成後是否刪除原始檔 * 使用 Boolean 包裝類進行判斷,True / true 為 true,False / false 為 false,其他依然為 false */ public static String isDelete; /** * 在解壓檔案時發生異常的集合 * Key:檔名 * Value:異常物件 */
public static final HashMap<File, Exception> unZipFailedMap = new HashMap<>(); /** * 找到相關的檔案數量 */ public static int foundCount = 0; /** * 成功解壓的檔案數量 */ public static int succeedCount = 0; /** * 解壓失敗的檔案數量 */ public static int unZipFailedCount = 0; /** * 刪除失敗的檔案個數 */ public static int deleteFailedCount = 0; /** * 刪除失敗的檔名 */ public static final HashSet<File> deleteFailedNameList = new HashSet<>(); public static void main(String[] args) { input(); if (new File(workPath).exists()) { Thread t1 = new Thread(new FindZipFile(new File(workPath))); Thread t2 = new Thread(new UnZipFile(ZIP_QUEUE)); t1.start(); t2.start(); while (true) { if (!t1.isAlive() && ZIP_QUEUE.isEmpty()) { isFlag = true; if (!t2.isAlive()) { System.out.println ( "\n\n\n" + "共找到了 " + foundCount + " 個檔案\n" + "成功解壓了 " + succeedCount + " 個檔案\n" + unZipFailedCount + " 個檔案解壓失敗,以下是失敗原因:" ); Set<Map.Entry<File, Exception>> failedElement = unZipFailedMap.entrySet(); for (Map.Entry<File, Exception> fileExceptionEntry : failedElement) { System.out.println("檔案:" + fileExceptionEntry.getKey() + " 異常:" + fileExceptionEntry.getValue()); } if (deleteFailedCount > 0) { System.out.println("另外,還有一些檔案刪除失敗,可能是在解壓過程中失敗了導致它們不被刪除,它們是:"); for (File file : deleteFailedNameList) { System.out.println(file); } } break; } } } }else{ System.out.println("提供的工作路徑不準確"); } } private static void input() { System.out.println("提供一個工作路徑:"); workPath = SCANNER.nextLine(); System.out.println("成功解壓完成後是否刪除原始檔(true / false):"); isDelete = SCANNER.nextLine(); } } class UnZipFile extends Thread { private final ConcurrentLinkedQueue<File> zipQueue; private static final int BUFFER_SIZE = 2 * 1024; public UnZipFile(ConcurrentLinkedQueue<File> zipQueue) { this.zipQueue = zipQueue; } @Override public void run() { do { if (!zipQueue.isEmpty()) { File file = zipQueue.poll(); String fileName = file.getName(); File destPathName = new File(file.getParent(), fileName.substring(0, fileName.indexOf("."))); System.out.println(destPathName.mkdirs()); unZip(file, destPathName.toString()); } } while (!UnZip.isFlag); } public void unZip(File srcFile, String destDirPath) throws RuntimeException { long start = System.currentTimeMillis(); // 開始解壓 ZipFile zipFile = null; FileOutputStream fos = null; InputStream is = null; try { zipFile = new ZipFile(srcFile, Charset.forName("GBK")); Enumeration<?> entries = zipFile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = (ZipEntry) entries.nextElement(); File unZipPathName = new File(entry.getName()); if (!unZipPathName.isDirectory()){ if (unZipPathName.getName().contains(".zip")) { zipQueue.add(new File(srcFile.getParentFile(), unZipPathName.toString())); System.out.println("俄羅斯套娃檔案:" + unZipPathName); } } System.out.println("解壓:" + unZipPathName); // 如果是資料夾,就建立個資料夾 if (entry.isDirectory()) { String dirPath = destDirPath + File.separator + entry.getName(); File dir = new File(dirPath); if(dir.mkdirs()){ System.out.println("No need to create"); } } else { // 如果是檔案,就先建立一個檔案,然後用io流把內容copy過去 File targetFile = new File(destDirPath + File.separator + entry.getName()); // 保證這個檔案的父資料夾必須要存在 if(!targetFile.getParentFile().exists()){ if(targetFile.getParentFile().mkdirs()){ System.out.println("No need to create"); } } if (targetFile.createNewFile()){ System.out.println("No need to create"); } // 將壓縮檔案內容寫入到這個檔案中 is = zipFile.getInputStream(entry); fos = new FileOutputStream(targetFile); int len; byte[] buf = new byte[BUFFER_SIZE]; while ((len = is.read(buf)) != -1) { fos.write(buf, 0, len); } fos.flush(); if (Boolean.parseBoolean(UnZip.isDelete)){ if(srcFile.delete()){ System.out.println("成功刪除:" + srcFile); }else{ UnZip.deleteFailedNameList.add(srcFile); UnZip.deleteFailedCount++; } } } } long end = System.currentTimeMillis(); UnZip.succeedCount++; System.out.println("解壓完成,耗時:" + (end - start) +" ms"); } catch (Exception e) { e.printStackTrace(); UnZip.unZipFailedCount++; UnZip.unZipFailedMap.put(srcFile, e); } finally { if(zipFile != null){ try { zipFile.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } if (is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } } class FindZipFile extends Thread { private final File file; public FindZipFile(File file) { this.file = file; } @Override public void run() { find(file); } public void find(File path){ File[] files = path.listFiles(); if (files != null) { for (File file : files) { if (file.isDirectory()){ find(file); }else{ UnZip.foundCount++; String absolutePath = file.getAbsolutePath(); String[] split = absolutePath.split("\\."); if ("zip".equalsIgnoreCase(split[split.length - 1])){ UnZip.ZIP_QUEUE.add(file); } } } } } }