1. 程式人生 > >ZIP解壓縮檔案的工具類【支援多級目錄|全】

ZIP解壓縮檔案的工具類【支援多級目錄|全】

                              

                             ZIP解壓縮檔案的工具類【支援多級目錄|全】




作者: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");
	}
}



實踐出真知,希望廣大讀者動手操作,如問題可以反饋,共同探討。。。