Java Zip應用

應用系統中使用jdk原生的包進行解壓縮時報錯,後來改用antzip沒問題。

使用JDK自帶的類進行解壓縮,代碼如下:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

//import org.apache.axis.utils.StringUtils;
import org.apache.log4j.Logger;

public class Utils {
	private static final Logger log = Logger.getLogger(Utils.class);
	
	/**
	 * 工具類,私有構造函數防止外部直接實例化
	 */
	private Utils(){
		
	}
	
	/** 文件分隔符 */
	public static final String FILE_SEPARATOR = System.getProperty("file.separator");
	
	/** 行分隔符 */
	public static final String LINE_SEPARATOR = System.getProperty("line.separator");
	
	/** 用戶工作目錄 */
	public static final String USER_DIR = System.getProperty("user.dir");
	
	/**
	 * 格式化字符串爲固定長度
	 * @param original String 原始字符串
	 * @param len  int 需要格式化的長度
	 * @return 格式化後的字符串
	 */
	public static String formatString(String original,int len){
		// 原始字符串爲null,轉換爲""字符串
		if(null == original){
			original = "";
		}
		// 返回變量
		StringBuffer result = new StringBuffer();
		// 原始字符串長度
		int oriLength = original.length();
		// 需要填充長度
		int fillLength = len - oriLength;
		
		if(fillLength < 0){
			// 原始字符串長度>需要格式化的長度,對原始字符串進行截取len變量的長度
			result.append(original.substring(0,len));
		} else {
			result.append(original);
			for (int i = 0; i < fillLength; i++) {
				result.append(" ");
			}
		}
		return result.toString();
	}
	
	/**
	 * 文件路徑結尾檢查
	 * @param filePath
	 * @return
	 */
	public static String checkFilePathEnd(String filePath){
		if(filePath.endsWith(Utils.FILE_SEPARATOR)){
			return filePath;
		} else {
			return filePath + Utils.FILE_SEPARATOR;
		}
	}
	
	/**
	 * 格式化日期,默認格式yyyy-MM-dd hh:mm:ss
	 * @param date
	 * @return
	 */
	public static String formateDate(Date date){
		return formateDate(date, "yyyy-MM-dd HH:mm:ss");
	}
	/**
	 * 格式化日期,默認格式yyyy-MM-dd hh:mm:ss
	 * @param date
	 * @return
	 */
	public static String formateDate(Date date, String format){
		if (date == null){
			return "";
		} else {
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			return sdf.format(date);
		}
	}
	
	/**
	 * 按指定日期格式,以當前系統時間爲基礎進行格式化
	 * @param format 日期格式
	 * @return 如果格式不存在,返回"yyyy-MM-dd HH:mm:ss"格式日期
	 */
	public static String formateDate(String format) {
		if (format == null || format.equals("") || format.length() == 0) {
			return formateDate(new Date());
		} else {
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			return sdf.format(new Date());
		}
		
	}
	
	/**
	 * 格式化字符串爲日期
	 * @param str
	 * @return
	 */
	public static Date formateString2Date(String str) {
		if(str.trim().equals("")){
			return null;
		}
		Date date = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			date = sdf.parse(str);
		} catch (ParseException e) {
			log.error("String '" + str + "' convert to date format 'yyyy-MM-dd HH:mm:ss' occur error.", e);
		}
		return date;
	}
	
//	/**
//	 * MQ消息字節轉換爲MessageHead對象
//	 * @param messageBytes
//	 * @return
//	 */
//	public static MessageHead bytesToMessageHead(byte[] messageBytes){
//		MessageHead head = new MessageHead();
//		head.setMessageVersion(new String(messageBytes,0,32).trim());
//		head.setMessageType(new String(messageBytes,32,16).trim());
//		head.setSender(new String(messageBytes,48,16).trim());
//		head.setReceiver(new String(messageBytes,64,16).trim());
//		head.setFileName(new String(messageBytes,80,64).trim());
//		head.setSendTime(formateString2Date(new String(messageBytes,144,19)));
//		head.setQuarantineTime(formateString2Date(new String(messageBytes,163,19)));
//		head.setShareTime(formateString2Date(new String(messageBytes,182,19)));
//		head.setReceiveTime(formateString2Date(new String(messageBytes,201,19)));
//		head.setPrimaryInfo(new String(messageBytes,220,64).trim());
//		return head;
//	}
	
	/**
	 * 獲取應用根路徑
	 * @return 發生異常返回null
	 */
	public static String getAppPath(){
		String appPath = null;
		try {
			File file = new File(".");
			appPath = file.getCanonicalPath();
		} catch (Exception e) {
		}
		return appPath;
	}
	
	/**
	 * 關閉輸入字節流
	 * @param is 輸入字節流
	 */
	public static void closeInputStream(InputStream is){
		if(is != null){
			try {
				is.close();
			} catch (Exception e) {
				log.error("InputStream close failed.",e);
			}
		}
	}
	
	/**
	 * 關閉輸出字節流
	 * @param os 輸出字節流
	 */
	public static void closeOutputStream(OutputStream os){
		if(os != null){
			try {
				os.close();
			} catch (IOException e) {
				log.error("OutputStream close failed.",e);
			}
		}
	}
	
	/**
	 * 在指定路徑後加上當天日期,並判斷指定的路徑是否存在,不存在則創建目錄
	 * @param path 指定路徑
	 */
	public static String genNowDatePath(String path) {
		// 在當前路徑後加上日期
		String resultPath = checkFilePathEnd(path) + formateDate("yyyy-MM-dd");
		// 檢查路徑是否存在,不存在則創建
		File file = new File(checkFilePathEnd(path) + formateDate("yyyy-MM-dd"));
		if (!file.exists()) {
			file.mkdirs();
		}
		return resultPath;
	}
	
	/**
	 * 檢查路徑是否存在,不存在則創建
	 * @param path 路徑
	 */
	public static void checkPath(String path) {
		try {
			File file = new File(path);
			if (!file.exists()) {
				log.info("file path[ " + path + " ] not exists, now create!!!");
				file.mkdirs();
			}
		} catch (SecurityException e) {
			log.error("Check path error, was not allowed to read check file existance,file:[" + path + "].", e);
		}
	}
	
	/**
	 * 獲取本機IP地址
	 * 
	 * @return ip 返回網卡綁定的4位IP地址 
	 */
	public static String getLocalIP() {
		String ip = "";
		try {
			Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
			while(nis.hasMoreElements()) {
				NetworkInterface ni = nis.nextElement();
				if (!ni.getName().startsWith("eth")) {
					continue;
				}
				Enumeration<InetAddress> ias = ni.getInetAddresses();
				while (ias.hasMoreElements()) {
					InetAddress ia = ias.nextElement();
					if (ia instanceof Inet6Address) {
						continue;
					}
					ip = ia.getHostAddress();
				}
			}
		} catch (SocketException e) {
			log.error("Get host IP address error.",e);
		}
		return ip;
	}
	
	/**
	 * 將文件進行zip壓縮
	 * 壓縮後的文件保存在源文件所在目錄下,壓縮文件名爲源文件名去除後綴加上.zip
	 * 例如:源文件E:\message\test.xml,壓縮後文件E:\message\test.zip
	 * @param srcFile 源文件File對象
	 * @return File 壓縮後的目標文件
	 */
	public static File fileToZip(File srcFile) throws IOException{
		FileInputStream fin = null;
		File zipFile = null;
		ZipEntry entry = null;
		// 獲取文件名
		String fileName = srcFile.getName();
		// 獲取entry名稱
		String entryName = fileName.substring(0, fileName.lastIndexOf("."));
		// 獲取不包含後綴的文件名稱
		fileName = fileName.substring(0, fileName.indexOf("."));
		// 獲取文件所在路徑
		String path = srcFile.getPath();
		path = path.substring(0, path.lastIndexOf(File.separator) + 1);
		try {
			fin = new FileInputStream(srcFile);
			zipFile = new File(path + fileName + ".zip");
			// 創建一個zip輸出流來壓縮數據並寫入到zip文件 
			ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
			// 做一個ZipEntry
			entry = new ZipEntry(entryName);
			// 存儲項信息到壓縮文件
			out.putNextEntry(entry);
			
			byte[] buffer = new byte[102400];
			int reader;
			while ((reader=fin.read(buffer)) > 0) {
				out.write(buffer, 0, reader);
			}
			out.closeEntry();
			fin.close();
			out.close();
		} catch (IOException e) {
			log.error("File [" + srcFile.getAbsolutePath() + "] compress to zip file error.",e);
			throw e;
		}
		return zipFile;
	}
	
	/**
	 * zip文件解壓縮
	 * 將zip文件進行解壓縮,解壓縮後的文件保存到zip文件的同級目錄中
	 * 
	 * @param srcFile zip文件
	 * @return 解壓後的文件列表
	 */
	public static List<File> unzipFile(File srcFile) throws Exception{
		List<File> listFile = new ArrayList<File>();
		File targetFile = null;
		try {
			// 根據ZIP文件創建ZipFile對象
			ZipFile zipFile = new ZipFile(srcFile);
			ZipEntry entry = null;
			String entryName;
			String targetFileName;
			byte[] buffer = new byte[10240];
			int len = 0;
			// 獲取ZIP文件裏所有的entry
            Enumeration<?> entrys = zipFile.entries();
            // 遍歷所有entry
            while(entrys.hasMoreElements()) {
            	entry = (ZipEntry)entrys.nextElement();
            	// 獲得entry的名字
            	entryName =  entry.getName();
            	targetFileName = srcFile.getParent() + File.separator + entryName;
            	if (!entry.isDirectory()) {
            		targetFile = new File(targetFileName);
            		//打開文件輸出流
                	FileOutputStream os = new FileOutputStream(targetFile);
                	//從ZipFile對象中打開entry的輸入流
                	InputStream  is = zipFile.getInputStream(entry);
                	while ((len = is.read(buffer)) > 0){
                		os.write(buffer, 0, len);
                	}
                	//關閉流
                	os.close( );
                	is.close( );
                	listFile.add(targetFile);
            	}
            }
            zipFile.close();
		} catch (Exception e) {			
			log.error("File [" + srcFile.getAbsolutePath() + "] unzip error.", e);
			//add by rick 2011-07-07 文件在解壓過程中失敗,則刪除部分已經解壓的文件			
			try {
				if(null!=listFile && !listFile.isEmpty()){
					for (int i=0;i<listFile.size();i++) {
						File f = (File) listFile.get(i);
						f.delete();				}
				}
			} catch (Exception e2) {
				throw e2;
			}			
			throw e;
		}
		return listFile;
	}
	
	/**
	 * zip文件解壓縮
	 * 將zip文件進行解壓縮,解壓縮後的文件保存到zip文件的同級目錄中
	 * 
	 * @param srcFile zip文件
	 * @return 解壓後的文件列表
	 */
	public static List<File> unzipFileNew(File srcFile) throws Exception{
		
		List<File> listFile = new ArrayList<File>();
		File targetFile = null;
		try {
			// 根據ZIP文件創建ZipFile對象
			ZipFile zipFile = new ZipFile(srcFile);
			ZipEntry entry = null;
			String entryName;
			String targetFileName;
			byte[] buffer = new byte[10];
			int len = 0;
			// 獲取ZIP文件裏所有的entry
            Enumeration<?> entrys = zipFile.entries();
            // 遍歷所有entry
            while(entrys.hasMoreElements()) {
            	entry = (ZipEntry)entrys.nextElement();
            	// 獲得entry的名字
            	entryName =  entry.getName();
            	targetFileName = srcFile.getParent() + File.separator + entryName;
            	if (!entry.isDirectory()) {
            		targetFile = new File(targetFileName);
            		//打開文件輸出流
                	FileOutputStream os = new FileOutputStream(targetFile);
                	//從ZipFile對象中打開entry的輸入流
                	InputStream  is = zipFile.getInputStream(entry);
//                	while ((len = is.read(buffer)) !=-1){
//                		os.write(buffer, 0, len);
//                	}
                	int ch = is.read(buffer, 0, 10);  
                    
                    while (ch != -1) {  
                    	os.write(buffer, 0, ch);  
                        ch = is.read(buffer, 0, 1024);  
                    }  
                	//關閉流
                	os.close( );
                	is.close( );
                	listFile.add(targetFile);
            	}
            }
            zipFile.close();
		} catch (Exception e) {			
			log.error("File [" + srcFile.getAbsolutePath() + "] unzip error.", e);
			//add by rick 2011-07-07 文件在解壓過程中失敗,則刪除部分已經解壓的文件			
			try {
				if(null!=listFile && !listFile.isEmpty()){
					for (int i=0;i<listFile.size();i++) {
						File f = (File) listFile.get(i);
						f.delete();				}
				}
			} catch (Exception e2) {
				throw e2;
			}			
			throw e;
		}
		return listFile;
	}
	
//	public void unzipFileIntoDirectory(File archive, File destinationDir) 
//    throws Exception {
//    final int BUFFER_SIZE = 1024;
//    BufferedOutputStream dest = null;
//    FileInputStream fis = new FileInputStream(archive);
//    ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
//    ZipEntry entry;
//    File destFile;
//    while ((entry = zis.getNextEntry()) != null) {
//        destFile = FilesystemUtils.combineFileNames(destinationDir, entry.getName());
//        if (entry.isDirectory()) {
//            destFile.mkdirs();
//            continue;
//        } else {
//            int count;
//            byte data[] = new byte[BUFFER_SIZE];
//            destFile.getParentFile().mkdirs();
//            FileOutputStream fos = new FileOutputStream(destFile);
//            dest = new BufferedOutputStream(fos, BUFFER_SIZE);
//            while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
//                dest.write(data, 0, count);
//            }
//            dest.flush();
//            dest.close();
//            fos.close();
//        }
//    }
//    zis.close();
//    fis.close();
//}

	
	/**
	 * 文件移動
	 * 從源文件移動到目標文件
	 * 
	 * @param src 源文件
	 * @param dst 目標文件
	 * @return 移動是否成功
	 */
	public static boolean moveFile(File src, File dst) {
		boolean result = true;
        try {
			if(src.getPath().equals(dst.getPath()))
			    return true;
			InputStream in = new FileInputStream(src);
			OutputStream out = new FileOutputStream(dst);
			byte[] buf = new byte[1024];
			int len;
			while ((len = in.read(buf)) > 0) {
			    out.write(buf, 0, len);
			}
			in.close();
			out.close();
			// 刪除源文件
			src.delete();
		} catch (Exception e) {
			result = false;
			log.error("Move file " + src.getPath() + " to " + dst.getPath() + " error.",e);
		}
		return result;
    }
	
	public static String checkDateString14(String str) {
		String result = null;
		 //YYYYMMDDHHMISS 字符串只能爲14位,多了截取,少了補0
//		if(!StringUtils.isEmpty(str)) {
		if(!str.equals("")) {
			if(str.length() > 14) {
				result = str.substring(0, 14);
			} else if(str.length() < 14) {
				int i = 14 - str.length();
				for (int j = 0; j < i; j++) {
					str += "0";
				}
				result = str;
			}
		}
		return result;
	}
	public static void main(String[] args) {
		//System.out.println(formatString("abc",6)+";");
		//System.out.println(formatString("12345678", 6));
		try {
			File f = new File("F:/test/t34/123.zip.bak");
			List<File> ls = Utils.unzipFile(f);
			System.out.println("F-->" + ls);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

 

改用ant zip進行解壓縮代碼如下:

import java.io.*; 

import org.apache.tools.zip.*; 
import java.util.Enumeration; 
/** 
*功能:zip壓縮、解壓(支持中文文件名) 
*說明:本程序通過使用Apache Ant裏提供的zip工具org.apache.tools.zip實現了zip壓縮和解壓功能. 
*   解決了由於java.util.zip包不支持漢字的問題。 
*   使用java.util.zip包時,當zip文件中有名字爲中文的文件時, 
*   就會出現異常:"Exception  in thread "main " java.lang.IllegalArgumentException  
*               at   java.util.zip.ZipInputStream.getUTF8String(ZipInputStream.java:285) 
*注意: 
*   1、使用時把ant.jar放到classpath中,程序中使用import org.apache.tools.zip.*; 
*   2、Apache Ant 下載地址:[url]http://ant.apache.org/[/url] 
*   3、Ant ZIP API:[url]http://www.jajakarta.org/ant/ant-1.6.1/docs/mix/manual/api/org/apache/tools/zip/[/url] 
*   4、本程序使用Ant 1.7.1 中的ant.jar 
* 
*僅供編程學習參考. 
* 
*@author Winty 
*@date   2008-8-3 
*@Usage: 
*   壓縮:java AntZip -zip "directoryName" 
*   解壓:java AntZip -unzip "fileName.zip" 
*/ 

public class AntZip{ 
    private ZipFile         zipFile; 
    private ZipOutputStream zipOut;     //壓縮Zip 
    private ZipEntry        zipEntry; 
    private static int      bufSize;    //size of bytes 
    private byte[]          buf; 
    private int             readedBytes; 
     
    public AntZip(){ 
        this(512); 
    } 

    public AntZip(int bufSize){ 
        this.bufSize = bufSize; 
        this.buf = new byte[this.bufSize]; 
    } 
     
    //壓縮文件夾內的文件 
    public void doZip(String zipDirectory){//zipDirectoryPath:需要壓縮的文件夾名 
        File file; 
        File zipDir; 

        zipDir = new File(zipDirectory); 
        String zipFileName = zipDir.getName() + ".zip";//壓縮後生成的zip文件名 

        try{ 
            this.zipOut = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFileName))); 
            handleDir(zipDir , this.zipOut); 
            this.zipOut.close(); 
        }catch(IOException ioe){ 
            ioe.printStackTrace(); 
        } 
    } 

    //由doZip調用,遞歸完成目錄文件讀取 
    private void handleDir(File dir , ZipOutputStream zipOut)throws IOException{ 
        FileInputStream fileIn; 
        File[] files; 

        files = dir.listFiles(); 
     
        if(files.length == 0){//如果目錄爲空,則單獨創建之. 
            //ZipEntry的isDirectory()方法中,目錄以"/"結尾. 
            this.zipOut.putNextEntry(new ZipEntry(dir.toString() + "/")); 
            this.zipOut.closeEntry(); 
        } 
        else{//如果目錄不爲空,則分別處理目錄和文件. 
            for(File fileName : files){ 
                //System.out.println(fileName); 

                if(fileName.isDirectory()){ 
                    handleDir(fileName , this.zipOut); 
                } 
                else{ 
                    fileIn = new FileInputStream(fileName); 
                    this.zipOut.putNextEntry(new ZipEntry(fileName.toString())); 

                    while((this.readedBytes = fileIn.read(this.buf))>0){ 
                        this.zipOut.write(this.buf , 0 , this.readedBytes); 
                    } 

                    this.zipOut.closeEntry(); 
                } 
            } 
        } 
    } 

    //解壓指定zip文件 
    public void unZip(String unZipfileName){//unZipfileName需要解壓的zip文件名 
        FileOutputStream fileOut; 
        File file; 
        InputStream inputStream; 
        File srcFile = new File(unZipfileName);
        try{ 
            this.zipFile = new ZipFile(unZipfileName); 

            for(Enumeration entries = this.zipFile.getEntries(); entries.hasMoreElements();){ 
                ZipEntry entry = (ZipEntry)entries.nextElement(); 

                String targetFileName = srcFile.getParent() + File.separator + entry.getName();
                file = new File(targetFileName); 
                if(entry.isDirectory()){ 
                    file.mkdirs(); 
                } 
                else{ 
                    //如果指定文件的目錄不存在,則創建之. 
                    File parent = file.getParentFile(); 
                    if(!parent.exists()){ 
                        parent.mkdirs(); 
                    } 

                    inputStream = zipFile.getInputStream(entry); 

                    fileOut = new FileOutputStream(file); 
                    while(( this.readedBytes = inputStream.read(this.buf) ) > 0){ 
                        fileOut.write(this.buf , 0 , this.readedBytes ); 
                    } 
                    fileOut.close(); 

                    inputStream.close(); 
                }    
            } 
            this.zipFile.close(); 
        }catch(IOException ioe){ 
            ioe.printStackTrace(); 
        } 
    } 

    //設置緩衝區大小 
    public void setBufSize(int bufSize){ 
        this.bufSize = bufSize; 
    } 

    //測試AntZip類 
    public static void main(String[] args)throws Exception{ 
        if(args.length==2){ 
            String name = args[1]; 
            AntZip zip = new AntZip(); 

            if(args[0].equals("-zip")) 
                zip.doZip(name); 
            else if(args[0].equals("-unzip")) 
                zip.unZip(name); 
        } 
        else{ 
            System.out.println("Usage:"); 
            System.out.println("壓縮:java AntZip -zip directoryName"); 
            System.out.println("解壓:java AntZip -unzip fileName.zip"); 
            throw new Exception("Arguments error!"); 
        } 
    } 
}

 

ant zip測試類:

public class TestAntZip {

	/** 
	 * @Title: main 
	 * @Description: TODO
	 * @param @param args   
	 * @return void  
	 * @throws 
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		AntZip az = new AntZip();
		az.unZip("F:\\1234\\CN_MT2101_1p0_5304192444043_20160525103427898.zip");
	}

}

 ant zip需要下載ant.jar

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章