ZIP解壓縮檔案的工具類【支援多級目錄|全】
阿新 • • 發佈:2019-01-11
作者:Vashon
網上有很多的加壓縮示例程式碼,但是都只是支援一級目錄的操作,如果存在多級目錄的話就不行了。本解壓縮工具類經過多次檢查及重構,最終分享給大家。
package com.ywx.ziputils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; /** * ZIP解壓縮檔案的工具類,檔案可以是多級目錄的結構進行解壓,壓縮操作. * @author yangwenxue(Vashon) * */ public class ZipUtil { /** * 壓縮檔案操作 * @param filePath 要壓縮的檔案路徑 * @param descDir 壓縮檔案的儲存路徑 * @throws IOException */ public static void zipFiles(String filePath,String descDir) throws IOException{ ZipOutputStream zos=null; try { //建立一個zip輸出流 zos=new ZipOutputStream(new FileOutputStream(descDir)); //啟動壓縮 startZip(zos,"",filePath); System.out.println("=============壓縮完畢============="); } catch (FileNotFoundException e) { //壓縮失敗,則刪除建立的檔案 File zipFile=new File(descDir); if(zipFile.exists()){ zipFile.delete(); } e.printStackTrace(); }finally{ if(zos!=null){ try { zos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 對目錄中所有檔案遞迴遍歷進行壓縮 * @param zos 壓縮輸出流 * @param oppositePath 在zip檔案中的相對路徑 * @param filePath 要壓縮的檔案路徑 * @throws IOException */ private static void startZip(ZipOutputStream zos, String oppositePath, String filePath) throws IOException { File file=new File(filePath); if(file.isDirectory()){//如果是壓縮目錄 File[] files=file.listFiles();//列出所有目錄 for(int i=0;i<files.length;i++){ File aFile=files[i]; if(aFile.isDirectory()){//如果是目錄,修改相對地址 String newoppositePath=oppositePath+aFile.getName()+"/"; //壓縮目錄,這是關鍵,建立一個目錄的條目時,需要在目錄名後面加多一個"/" ZipEntry entry=new ZipEntry(newoppositePath); zos.putNextEntry(entry); zos.closeEntry(); startZip(zos, newoppositePath, aFile.getPath()); }else{//如果不是目錄,則進行壓縮 zipFile(zos,oppositePath,aFile); } } }else{//如果是壓縮檔案,直接呼叫壓縮方法進行壓縮 zipFile(zos, oppositePath, file); } } /** * 壓縮單個檔案到目錄中 * @param zos zip輸出流 * @param oppositePath 在zip檔案中的相對路徑 * @param file 要壓縮的檔案 */ private static void zipFile(ZipOutputStream zos, String oppositePath, File file) { //建立一個zip條目,每個zip條目都必須是相對於跟路徑 InputStream is=null; try { ZipEntry entry=new ZipEntry(oppositePath+file.getName()); //將條目儲存到zip壓縮檔案當中 zos.putNextEntry(entry); //從檔案輸入流當中讀取資料,並將資料寫到輸出流當中 is=new FileInputStream(file); //====這種壓縮速度很快 int length=0; int bufferSize=1024; byte[] buffer=new byte[bufferSize]; while((length=is.read(buffer, 0, bufferSize))>=0){ zos.write(buffer, 0, length); } //===============以下壓縮速度很慢================= // int temp=0; // // while((temp=is.read())!=-1){ // zos.write(temp); // } //========================================== zos.closeEntry(); } catch (IOException e) { e.printStackTrace(); }finally{ if(is!=null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 解壓檔案操作 * @param zipFilePath zip檔案路徑 * @param descDir 解壓出來的檔案儲存的目錄 */ public static void unZiFiles(String zipFilePath,String descDir){ File zipFile=new File(zipFilePath); File pathFile=new File(descDir); if(!pathFile.exists()){ pathFile.mkdirs(); } ZipFile zip=null; InputStream in=null; OutputStream out=null; try { zip=new ZipFile(zipFile); Enumeration<?> entries=zip.entries(); while(entries.hasMoreElements()){ ZipEntry entry=(ZipEntry) entries.nextElement(); String zipEntryName=entry.getName(); in=zip.getInputStream(entry); String outPath=(descDir+"/"+zipEntryName).replace("\\*", "/"); //判斷路徑是否存在,不存在則建立檔案路徑 File file=new File(outPath.substring(0, outPath.lastIndexOf('/'))); if(!file.exists()){ file.mkdirs(); } //判斷檔案全路徑是否為資料夾,如果是上面已經建立,不需要解壓 if(new File(outPath).isDirectory()){ continue; } out=new FileOutputStream(outPath); byte[] buf=new byte[4*1024]; int len; while((len=in.read(buf))>=0){ out.write(buf, 0, len); } in.close(); System.out.println("==================解壓完畢=================="); } } catch (Exception e) { System.out.println("==================解壓失敗=================="); e.printStackTrace(); }finally{ try { if(zip!=null){ zip.close(); } if(in!=null){ in.close(); } if(out!=null){ out.close(); } } catch (IOException e) { e.printStackTrace(); } } } @SuppressWarnings("static-access") public static void main(String args[]) throws IOException{ // long startTimes=System.currentTimeMillis(); // new ZipUtil().zipFiles("f:"+File.separator+"Vashon2Xiaoai", "f:"+File.separator+"Vashon2Xiaoai_vvv.zip"); // long times=System.currentTimeMillis()-startTimes; // System.out.println("耗時:"+times/1000+"秒"); new ZipUtil().unZiFiles("f:"+File.separator+"Vashon2Xiaoai_vvv.zip", "f:"+File.separator+"vvvvss"); } }