package com.test;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
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.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.utils.IOUtils;

/**
*
 * class name: ZipFileUtils
*
* 使用Apache Commons Compress 套件
*
* Apache Commons Compress software defines an API for working with compression and archive formats.
* These include: bzip2, gzip, pack200, xz and ar, cpio, jar, tar, zip, dump.
*
* 為何要使用此套件,因為使用java.util.zip套件作壓縮時,會中文檔名都會變亂碼。
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4820807
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4885817
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4244499
*
* 使用說明:
* 使用getInstance() 取得此 ZipFileUtils 物件。
* 可使用二個public方法。
* 1、unZip--解壓縮
* 2、doZip--使用壓縮檔
*
* * @author Levin Li */ public class ZipFileUtils { /** * 設定編碼,BIG5 */ private final static String ENCODING_NAME = "BIG5"; /** * 存放解壓了那些文件明細 */ private final static List RETURN_FILE_LIST_DETAILS = new ArrayList(); /** * test * * @param args */ public static void main(String[] args) throws Exception { unZip(new File("d:/ZipTest.zip"), "d:/ZipTest"); doZip("d:/ZipTest1/ZipTest/"); } /** * 解壓指定zip文件 * ex:unZip(new File("d:/ZipTest.zip"),new File("d:/ZipTest")) * * @param pUnZipfile * 需要解壓的zip文件名 * @param pOutFileDir * 目的位置 * @return List 將解壓了那些文件明細 * @throws IOException * @author Levin Li */ public static List unZip(final File pUnZipFile, final String pOutFileDir) throws IOException { return unZip(pUnZipFile, new File(pOutFileDir)); } /** * 解壓指定zip文件 * ex:unZip(new File("d:/ZipTest.zip"), "d:/ZipTest") * * @param pUnZipFile * 需要解壓的zip文件名 * @param pOutFileDir * 目的位置 * @return List 將解壓了那些文件明細 * @throws IOException * @author Levin Li */ public static List unZip(final File pUnZipFile, final File pOutFileDir) throws IOException { ZipFile zipFile = null; try { /* * ZipFile API * :http://commons.apache.org/compress/apidocs/org/apache * /commons/compress/archivers/zip/ZipFile.html */ zipFile = new ZipFile(pUnZipFile, ENCODING_NAME); System.out.println("in pUnZipfile path:" + pUnZipFile.getPath()); for (Enumeration files = zipFile.getEntries(); files.hasMoreElements();) { ZipArchiveEntry zipArchiveEntry = files.nextElement(); /* * File.separator 用法。 該系統有關的默認名稱分隔符。 file.separator的值。 * 在UNIX系統上,此字段的值是'/',Microsoft Windows系統上,它是'\ \'。 */ File outFile = new File(pOutFileDir.getPath() + File.separator + zipArchiveEntry.getName()); // 如果指定文件的不存在,則創建. System.out.println("nuZip to file Name:" + outFile.getName()); // 這裡是指同層的檔案文件是不是目錄 if (!outFile.isDirectory()) { // 取得上一層目錄目錄創建。 if (!outFile.getParentFile().exists()) { outFile.getParentFile().mkdirs(); } /* * IOUtils API: * http://commons.apache.org/compress/apidocs/org * /apache/commons/compress/utils/IOUtils.html Copies the * content of a InputStream into an OutputStream. Uses a * default buffer size of 8024 bytes. */ copyFile(zipFile.getInputStream(zipArchiveEntry), outFile); // 加入已解壓完成的檔案資訊 RETURN_FILE_LIST_DETAILS.add(outFile); } else { System.out.println("isDirectory:" + outFile.getName()); outFile.mkdirs(); } } } catch (IOException ioe) { System.out.println("unZip Error Message:pUnZipfile path:" + pUnZipFile.getPath()); errorMessage(ioe); throw ioe; } finally { try { if (null != zipFile) { zipFile.close(); } } catch (IOException ioe) { errorMessage(ioe); throw ioe; } } return RETURN_FILE_LIST_DETAILS; } public static void doZip(final String pToZipFileSource) throws IOException { File toZipFile = new File(pToZipFileSource); // 壓縮後生成的zip文件名 String toZipFileName = toZipFile.getName() + ".zip"; String toZipDir = toZipFile.getParent() + toZipFileName; if (toZipFile.isDirectory()) { toZipDir = pToZipFileSource + toZipFileName; } doZip(toZipFile, new File(toZipDir)); } public static void doZip(final String pToZipFileSource, final String pToZipFileDir) throws IOException { doZip(new File(pToZipFileSource), new File(pToZipFileDir)); } /** *
  * doZip 此方法可以壓一個File,
* 也可以壓一個目錄內的文件。
*
* ex1:doZip("d:/ZipTest/ZipTest/test.txt", "d:/test/ZipTest.zip")
* ex2:doZip("d:/ZipTest/ZipTest/", "d:/test/ZipTest.zip")
* ex3:doZip("d:/ZipTest/ZipTest/")
*
*
* * @param pToZipFileSource * 目的文件夾 * @param pToZipFileDir * 要壓到那個目錄及檔名名字 * @throws IOException * @author Levin Li */ public static void doZip(final File pToZipFileSource, final File pToZipFileDir) throws IOException { ZipArchiveOutputStream zipFileOutput = null; File temp = null; try { System.out.println("檔案名稱zipDirectory:" + pToZipFileDir.getPath()); temp = File.createTempFile("temp", ".zip"); System.out.println(temp.getPath()); // 產出檔位置 zipFileOutput = new ZipArchiveOutputStream(new FileOutputStream(temp)); zipFileOutput.setEncoding(ENCODING_NAME); compress(pToZipFileSource, zipFileOutput, ""); zipFileOutput.close(); copyFile(temp, pToZipFileDir); } catch (SecurityException se) { errorMessage(se); } catch (IOException ioe) { errorMessage(ioe); } catch (Exception e) { errorMessage(e); } finally { try { if (null != zipFileOutput) { zipFileOutput.close(); } // if (null != temp) { // temp.deleteOnExit(); // } } catch (IOException ioe) { errorMessage(ioe); throw ioe; } } } /** * 判斷是目錄還是文件 * * @param pFile * 來源檔 * @param pZipArchiveOut * 輸出ZipArchiveOutputStream * @param baseDir * 在壓縮檔內的基本目錄 * @throws IOException * @author Levin Li */ private static void compress(final File pToZipFileSource, final ZipArchiveOutputStream pZipFileOutput, final String baseDir) throws IOException { /* 判斷是目錄還是文件 */ if (pToZipFileSource.isDirectory()) { compressDirectory(pToZipFileSource, pZipFileOutput, baseDir); } else { compressFile(pToZipFileSource, pZipFileOutput, baseDir); } } /** * 壓縮一個目錄,不壓縮上一層目錄名字的zip的檔 。 * * @param pToZipFileSource * 來源檔 * @param pZipArchiveOut * 輸出ZipArchiveOutputStream * @param baseDir * 在壓縮檔內的基本目錄 * @throws IOException * @author Levin Li */ private static void compressDirectory(final File pToZipFileSource, final ZipArchiveOutputStream pZipFileOutput, final String baseDir) throws IOException { File[] files = pToZipFileSource.listFiles(); for (int i = 0; i < files.length; i++) { System.out.println("files[i].getName():" + files[i].getName()); compress(files[i], pZipFileOutput, baseDir + pToZipFileSource.getName() + File.separator); } } /** * 壓縮一個文件 * * @param pFile * 來源檔 * @param pZipArchiveOut * 輸出ZipArchiveOutputStream * @param baseDir * 在壓縮檔內的基本目錄 * @throws IOException * @author Levin Li */ private static void compressFile(final File pToZipFileSource, final ZipArchiveOutputStream pZipFileOutput, final String baseDir) throws IOException { try { System.out.println("ready compression of file for:" + pToZipFileSource.getName()); pZipFileOutput.putArchiveEntry(new ZipArchiveEntry(baseDir + pToZipFileSource.getName())); copyFile(pToZipFileSource, pZipFileOutput); pZipFileOutput.closeArchiveEntry(); } catch (IOException ioe) { errorMessage(ioe); } } /** * 複製 * * @param inputFile * 來源檔File * @param outputFile * 輸出File * * @throws IOException * @author Levin Li */ private static void copyFile(File inputFile, File outputFile) throws IOException { BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile)); copyFile(inputFile, outputStream); } private static void copyFile(InputStream inputStream, File outputFile) throws IOException { BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile)); copyFile(inputStream, outputStream); } private static void copyFile(File inputFile, OutputStream outputStream) throws IOException { BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(inputFile)); copyFile(inputStream, outputStream); } /** * 複製 * * @param inputStream * 來源檔InputStream * @param outputStream * 輸出File * * @throws IOException * @author Levin Li */ private static void copyFile(InputStream inputStream, OutputStream outputStream) throws IOException { try { IOUtils.copy(inputStream, outputStream); } catch (IOException ioe) { errorMessage(ioe); } finally { try { if (null != outputStream) { outputStream.close(); } if (null != inputStream) { inputStream.close(); } } catch (IOException ioe) { errorMessage(ioe); } } } /** * 複製 * * @param inputFile * 來源檔InputStream * @param zipArchiveOutputStream * 輸出 * * @throws IOException * @author Levin Li */ private static void copyFile(File inputFile, ZipArchiveOutputStream zipArchiveOutputStream) throws IOException { BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(inputFile)); try { IOUtils.copy(inputStream, zipArchiveOutputStream); } catch (IOException ioe) { errorMessage(ioe); } finally { try { if (null != inputStream) { inputStream.close(); } } catch (IOException ioe) { errorMessage(ioe); } } } /** * 顯示錯誤訊息 * * @param ioe * IOException * @author Levin Li */ private static void errorMessage(Exception e) { StringWriter stringWriter = new StringWriter(); e.printStackTrace(new PrintWriter(stringWriter)); System.out.println("Error Message:" + stringWriter.toString()); } }


maven 設定

    <dependency>
<groupid>org.apache.commons</groupid>
<artifactid>commons-compress</artifactid>
<version>1.0</version>
</dependency>


download JAR

參考資料







 















其它文章

arrow
arrow

    PG Levin Li 發表在 痞客邦 留言(0) 人氣()