1. 程式人生 > >java實現上傳zip解壓及判斷壓縮包資料夾功能

java實現上傳zip解壓及判斷壓縮包資料夾功能

直接上Service,通過程式碼看思路貫穿整個功能,很多工具類可以複用,檔案路徑可以去看我部落格裡的

(使用ResourceBundle國際化資原始檔讀取properties詳解) 這篇製作方法
url:
https://blog.csdn.net/qq_17025903/article/details/75949066

html頁面

 <span>ZIP:</span> <input type="file" style="width: 170px"  name="hostFileBatch"/><span id="hostCheckResult"></span><br/>  
 <input type="button" value="確認上傳" onclick="checkHostBatchRun()"/> 
 <input type="button" value="執行"  onclick="hostRun()" id="hostRunResult" disabled="disabled" > 
 <span id="hostResult"></span>

頁面js

function checkHostBatchRun(){
	
if(confirm("上傳重名檔案將會替換掉原有檔案,是否繼續上傳?")){
	//年
	var hostYear=$("#hostYear").val();
	//季度
	var quarter=$("#hostQuarter").find("option:selected").text();

 	$.ajax({
		type : "POST",
		cache : false,
		dataType : "json",
		data:new FormData($('#hostUploadForm')[0]),
        processData: false,//用於對data引數進行序列化處理 這裡必須false
        contentType: false, //必須 ?hostYear="+hostYear+"&quarter="+quarter"
		url : "../uploadController/hostUploadZipBatchRun.htm?hostYear="+hostYear+"&&quarter="+quarter+" ",
		success : function(obj) {
			/* alert(obj.data.msg); */
			var result=obj.data.msg;
			if(result==true){
				$("#hostCheckResult").text("上傳成功!").css("color","blue");
				$("#hostRunResult").attr("disabled",false);
			}else{
				$("#hostCheckResult").text("上傳失敗!").css("color","red");
			}
			
		}
	});	
   }
	
}	

Service

		//建立解析器
		MultipartHttpServletRequest mh=(MultipartHttpServletRequest) request;
		//獲得檔案  
		CommonsMultipartFile cmf=(CommonsMultipartFile) mh.getFile("hostFileBatch");
		//獲得原始檔名
		String oriName=cmf.getOriginalFilename(); 
		//拼接年+月
		String path=hostYear.concat(quarter);
//		String path=String.valueOf(year).concat(String.valueOf(month));
		String savePath=Commons.HOST_UPLOAD_PATH+"\\"+path; //儲存的路徑
//		File storeDirectory=new File(savePath);  
		//判斷是不是zip檔案
		if(oriName.matches(".*.zip")) {		
			//判斷檔案目錄是否存在
			File file=new File(savePath);
			//不存在 
			if(!file.exists()) {
				//建立資料夾
				file.mkdirs();
			}else {	
				//檔案存在則刪除
				deleteDir(file);
//				file.delete();
				file.mkdirs(); 
				//刪除檔案原始路徑
				int deletePath=uploadZipDao.deleteOldFile(oriName,savePath);
			}
			//獲取檔案
			FileItem fileItem=cmf.getFileItem();  
			try {	
				//解壓檔案到指定目錄
				FileUnZip.zipToFile(oriName, savePath);
			} catch (Exception e){
				e.printStackTrace();  
				new File(savePath,oriName).delete();  
			}
			fileItem.delete();	
			//儲存路徑檔名
			boolean result=addPath(oriName,savePath);
			if(result==true) {
				//執行批處理	
				return true;		
			}
			return false;
		}else {
			//不是zip則返回false
			return false;
		}	
	}

解壓工具類

package cn.secure.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;

public class FileUnZip {
	/**
     * 解壓zip檔案
     * @author 於公成
     * @param sourceFile,待解壓的zip檔案;
     *        toFolder,解壓後的存放路徑
     * @throws Exception
     **/

	public static void zipToFile(String sourceFile, String toFolder) throws Exception {
			String toDisk = toFolder;// 接收解壓後的存放路徑
			ZipFile zfile = new ZipFile(sourceFile, "gbk");// 連線待解壓檔案 "utf-8"會亂碼
			Enumeration zList = zfile.getEntries();// 得到zip包裡的所有元素
			ZipEntry ze = null;
			byte[] buf = new byte[1024];
			while (zList.hasMoreElements()) {
			ze = (ZipEntry) zList.nextElement();
			if (ze.isDirectory()) {
				// log.info("開啟zip檔案裡的資料夾:"+ ze.getName() +"skipped...");
				continue;
			}
			OutputStream outputStream = null;
			InputStream inputStream = null;
			try {
				// 以ZipEntry為引數得到一個InputStream,並寫到OutputStream中
				outputStream = new BufferedOutputStream(new FileOutputStream(getRealFileName(toDisk, ze.getName())));
				inputStream = new BufferedInputStream(zfile.getInputStream(ze));
				int readLen = 0;
				while ((readLen = inputStream.read(buf, 0, 1024)) != -1) {
					outputStream.write(buf, 0, readLen);
				}
				inputStream.close();
				outputStream.close();
			} catch (Exception e) {
				// log.info("解壓失敗:"+e.toString());
				throw new IOException("解壓失敗:" + e.toString());
			} finally {
				if (inputStream != null) {
					try {
						inputStream.close();
					} catch (IOException ex) {

					}
				}
				if (outputStream != null) {
					try {
						outputStream.close();
					} catch (IOException ex) {
						ex.printStackTrace();
					}
				}
				inputStream = null;
				outputStream = null;
			
				
			}

		}
		zfile.close();
	}

    /**
     * 
     * 給定根目錄,返回一個相對路徑所對應的實際檔名.
     * 
     * @param zippath
     *            指定根目錄
     * 
     * @param absFileName
     *            相對路徑名,來自於ZipEntry中的name
     * 
     * @return java.io.File 實際的檔案
     * 
     */

    private static File getRealFileName(String zippath, String absFileName) {
        // log.info("檔名:"+absFileName);
        String[] dirs = absFileName.split("/", absFileName.length());
        File ret = new File(zippath);// 建立檔案物件
        if (dirs.length > 1) {
            for (int i = 0; i < dirs.length - 1; i++) {
                ret = new File(ret, dirs[i]);
            }
        }
        if (!ret.exists()) {// 檢測檔案是否存在
            ret.mkdirs();// 建立此抽象路徑名指定的目錄
        }
        ret = new File(ret, dirs[dirs.length - 1]);// 根據 ret 抽象路徑名和 child
                                                    // 路徑名字串建立一個新 File 例項
        return ret;
    }
    

    
    
}


檔案遞迴刪除工具類(file.delete方法必須檔案為空才能刪除,所以用這個遞迴方法刪)

   /**
     * 遞迴刪除目錄下的所有檔案及子目錄下所有檔案
     * @param dir 將要刪除的檔案目錄
     */
    private static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (int i=0; i<children.length; i++) {	
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目錄此時為空,可以刪除
        return dir.delete(); 
    }

判斷zip壓縮包是否有資料夾思路

eg:所內 所外倆個資料夾

	/**
	 * 判斷是否存在所內所外倆個資料夾
	 * @param oriName
	 * @param savePath
	 * @return
	 * @throws Exception
	 */
	private boolean hasFileDirectory(String oriName, String savePath) throws Exception {
		  ZipFile zfile = new ZipFile(oriName, "gbk");// 連線待解壓檔案 "utf-8"會亂碼
	        Enumeration zList = zfile.getEntries();// 得到zip包裡的所	有元素
	        ZipEntry ze = null;
	        int count = 0;
	        while (zList.hasMoreElements()) {
	            ze = (ZipEntry) zList.nextElement();
	            if (ze.isDirectory()) {
	            	if(ze.getName().equals("所內/")) {
	            		count+=1;
	            	}
	            	if(ze.getName().equals("所外/")) {
	            		count+=1;
	            	}
	            }
	                // log.info("開啟zip檔案裡的資料夾:"+ ze.getName() +"skipped...");	      
	         }
	        if(count==2) {
	        	return true;
	        }
		return false;
	}