Zip壓縮和解壓縮工具類
阿新 • • 發佈:2019-02-18
依賴第三方jar包:ant-1.7.1.jar
/** * @Title: ZipUtils.java * @Package com.sz.mt.test.zip * @Description: TODO(ZIP壓縮及解壓工具類) * @author: LokChow * @version V1.0 */ package com.sz.mt.test.zip; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; import java.util.List; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Expand; import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipOutputStream; /** * @ClassName: ZipUtils * @Description: TODO(ZIP實現檔案的壓縮和解壓縮工具類) * @author LokChow * @date 2018-11-27 * */ public class ZipUtils { private static final int BUFFER_SIZE = 4 * 1024; /** * @Title: unzip * @Description: TODO(解壓zip格式壓縮包) * @param @param sourceZip 待解壓檔案路徑 * @param @param destDir 解壓後的路徑 * @param @return 引數 * @return boolean 返回型別 * @throws */ private static boolean unzip(String sourceZip, String destDir) { try { Project project = new Project(); Expand expand = new Expand(); expand.setProject(project); expand.setSrc(new File(sourceZip)); expand.setOverwrite(false); expand.setDest(new File(destDir)); /* * ant下的zip工具預設壓縮編碼為UTF-8編碼, * 而winRAR軟體壓縮是用的windows預設的GBK或者GB2312編碼 * 所以解壓縮時要制定編碼格式 */ expand.setEncoding("gbk"); expand.execute(); } catch (BuildException e) { e.printStackTrace(); return false; } return true; } /** * 遞迴壓縮方法 * @param sourceFile 原始檔 * @param zos zip輸出流 * @param name 壓縮後的名稱 * @param KeepDirStructure 是否保留原來的目錄結構,true:保留目錄結構; * false:所有檔案跑到壓縮包根目錄下(注意:不保留目錄結構可能會出現同名檔案,會壓縮失敗) * @throws Exception */ private static void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure) throws Exception{ if (!sourceFile.exists()) return; FileInputStream fis = null; byte buf[] = new byte[BUFFER_SIZE]; if (sourceFile.isFile()) { // 向zip輸出流中新增一個zip實體,構造器中name為zip實體的檔案的名字 zos.putNextEntry(new ZipEntry(name)); // copy檔案到zip輸出流中 int len; fis = new FileInputStream(sourceFile); while((len = fis.read(buf)) != -1){ zos.write(buf,0,len);//copy並寫到壓縮檔案中 } // 解壓完畢 zos.closeEntry(); fis.close(); }else{ File Listfiles[] = sourceFile.listFiles(); //沒有檔案 if (Listfiles == null || Listfiles.length == 0) { // 需要保留原來的檔案結構時,需要對空資料夾進行處理 if (KeepDirStructure) { // 空資料夾的處理 zos.putNextEntry(new ZipEntry(name+"/")); // 沒有檔案,不需要檔案的copy zos.closeEntry(); } }else{ for (File file : Listfiles) { // 判斷是否需要保留原來的檔案結構 if (KeepDirStructure) { // 注意:file.getName()前面需要帶上父資料夾的名字加一斜槓, // 不然最後壓縮包中就不能保留原來的檔案結構,即:所有檔案都跑到壓縮包根目錄下了 compress(file, zos, name+"/"+file.getName(), KeepDirStructure); }else{ compress(file, zos, file.getName(), KeepDirStructure); } } } } } /** * @Title: toZip1 * @Description: TODO(壓縮成ZIP) * @param srcDir 壓縮資料夾路徑 * @param out 壓縮檔案輸出流 * @param KeepDirStructure 是否保留原來的目錄結構,true:保留目錄結構; * false:所有檔案跑到壓縮包根目錄下(注意:不保留目錄結構可能會出現同名檔案,會壓縮失敗) * @return void 返回型別 * @throws RuntimeException 壓縮失敗會丟擲執行時異常 */ public static void toZip1(String srcDir, OutputStream out, boolean KeepDirStructure) throws RuntimeException{ long start = System.currentTimeMillis(); ZipOutputStream zos = null; try { zos = new ZipOutputStream(out); //設定檔名編碼方式(將系統的ZIP編碼格式設定為系統檔名編碼方式,否則中文名稱檔名亂碼及解壓時報異常.) zos.setEncoding(System.getProperty("sun.jnu.encoding")); File sourceFile = new File(srcDir); compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure); long end = System.currentTimeMillis(); System.out.println("壓縮完畢,共耗時:"+(end-start)/1000+"秒"); } catch (Exception e) { throw new RuntimeException("zip error from ZipUtils",e); }finally{ if (null != zos) { try { zos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * @Title: toZip * @Description: TODO(壓縮成ZIP 方法2) * @param srcFiles 需要壓縮的檔案列表 * @param out 壓縮檔案輸出流 * @throws RuntimeException 壓縮失敗會丟擲執行時異常 * @return void 返回型別 */ public static void toZip(List<File> srcFiles , OutputStream out)throws RuntimeException { long start = System.currentTimeMillis(); ZipOutputStream zos = null; FileInputStream fis = null; try { zos = new ZipOutputStream(out); for (File srcFile : srcFiles) { byte buf[] = new byte[BUFFER_SIZE]; // 向zip輸出流中新增一個zip實體,構造器中name為zip實體的檔案的名字 zos.putNextEntry(new ZipEntry(srcFile.getName())); int len; fis = new FileInputStream(srcFile); while((len = fis.read(buf)) != -1){ zos.write(buf, 0, len); } zos.closeEntry(); fis.close(); } long end = System.currentTimeMillis(); System.out.println("解壓完畢,共耗時:"+(end-start)/1000+"秒"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }catch (Exception e){ throw new RuntimeException("zip error from ZipUtils",e); }finally{ if (null != zos) { try { zos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public static void main(String[] args) { //測試toZip1壓縮 /*String srcPath = "F:\\我的工具\\你好.txt"; try { FileOutputStream fos1 = new FileOutputStream(new File("f:\\我的工具\\test01.zip")); toZip1(srcPath, fos1, true); } catch (FileNotFoundException e) { e.printStackTrace(); } */ //測試解壓 unzip("F:\\我的工具\\test01.zip", "F:\\"); } }