天天看點

zip檔案壓縮(轉)

zip檔案結構

zip檔案壓縮(轉)

     上面中的每一行都是一個條目,zip檔案就是由一個或者多個條目組成。

     條目在Java中對應ZipEntry類

建立zip壓縮檔案

     知道了zip檔案結構之後,大概就知道怎麼去建立一個zip壓縮檔案了。

     之前,先了解下建立普通的檔案都是經過以下幾個步驟:

     1、建立檔案輸出流FileOutputStream fout = new FileOutputStream(new File("XXX"));

     2、往檔案輸出流中寫入檔案内容,fout.write(XXX);

     3、關閉輸出流fout.close();

     這樣,一個普通的建立就是生成了

     既然zip壓縮檔案也是檔案,那麼它的建立也基本都差不多,隻是,zip檔案結構跟普通檔案有點差别,因為它裡面是由條目(ZipEntry)組成的。

     是以建立zip壓縮檔案的步驟如下:

     1、建立zip壓縮檔案輸出流

           ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File("XXX")));

     2、建立zip檔案條目

           ZipEntry entry = new ZipEntry(name)

           備注:name指定條目的名稱,例如上圖顯示的client.cer,這裡name可以帶路徑,例如:a/b/c/test.txt,這樣就是建立a/b/c這個目錄。

     3、将條目添加到zip檔案輸出流

          zos.putNextEntry(entry);

     4、建立被檔案的輸入流,讀取檔案内容,并寫入到zip壓縮檔案輸出流。這個時候,寫入的内容都屬于目前這個條目的。

         FileInputStream in = new FileInputStream(new File("XXX"));

     byte[]buffer = new byte[1024];

     int len = 0;

     while((len = in.read(buffer))!=-1){

          zos.write(buffer ,0 ,len);

     }

     in.close();

     5、關閉zip檔案輸出流

         zos.close()

zip亂碼問題解決

       使用Apache中的org.apache.tools.zip.ZipOutputStream類來替換Java自帶的ZipOutputStream類

       FileOutputStream fout = new FileOutputStream("f:\\abc.zip");

    ZipOutputStream out = new ZipOutputStream(fout);

    out.setEncoding("utf-8"); //這條語句時必須的,否則,生成中文條目時,無法打開zip檔案或者出現亂碼

    ZipEntry entry = new ZipEntry("測試檔案.txt");

    out.putNextEntry(entry);

誤解區:

    以前都是以為一個檔案或者目錄就對應zip檔案中的一個條目,其實并非一定是這樣的。解析如下:

    zip檔案是以條目來組織,操作zip檔案都是基于條目來進行的,是以,每次往條目新增内容時,

    得首先建立zip檔案條目,并将添加到zip檔案輸出,之後,zip輸出流,才認為之後寫入到輸出流中的

    内容都是屬于這個條目,直到zip輸出流中新增新的條目。不過一般來正常來說,都是一個檔案或者目錄就對應zip檔案中的一個條目。

    正常情況下,一個檔案或者目錄對應一個條目,如下圖:

zip檔案壓縮(轉)

       但是也可以将a.txt、b.txt的内容都隻寫入的一個條目c.txt

zip檔案壓縮(轉)

       生成的zip檔案結果圖:

zip檔案壓縮(轉)

       這裡可以發現,隻要沒有重新往zip檔案輸出流中添加新的條目,那麼,所有的内容都是寫入目前條目中。

自己封裝的一個zip壓縮工具類

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.util.ArrayList;

import java.util.zip.ZipEntry;

import java.util.zip.ZipOutputStream;

public class FilleUtils {

    /**

     * zip壓縮檔案,預設生成的壓縮檔案目錄與目前需要壓縮的檔案或者目錄同級

     * @param filePath  需要壓縮的檔案或者目錄

     * @return 傳回zip壓縮檔案路徑

     */

    public static String zip(String filePath) throws Exception{

         System.out.println("壓縮中..."); 

         String zipFilePath = null;

         File srcFile = new File(filePath);

         //獲得zip檔案路徑

         if(srcFile.isDirectory()){

             zipFilePath = srcFile.getParent() + srcFile.getName() + ".zip";

         }

         else{

             String zipFileName = "";

             if(srcFile.getName().indexOf(".")>-1)

                 zipFileName = srcFile.getName().substring(0 ,srcFile.getName().lastIndexOf(".")) + ".zip";

             else

                 zipFileName = srcFile.getName() + ".zip";

             zipFilePath = srcFile.getParent() + zipFileName;

         //開始進行壓縮

         ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFilePath));   

         BufferedOutputStream bo = new BufferedOutputStream(out);  

         zip(out, srcFile, srcFile.getName(), bo);  

         bo.close();  

         out.close(); 

         System.out.println("壓縮完成");  

         return zipFilePath;

    }

     * zip壓縮檔案

     * @param filePath

     * @param zipFilePath

    public static void zip(String filePath ,String zipFilePath) throws Exception{

         //檢查壓縮檔案路徑是否存在,不存在則建立

         File zipFile = new File(zipFilePath);

         if(!zipFile.exists()){

             zipFile.getParentFile().mkdirs();

         //開始壓縮

         out.close();  

     * 壓縮指定的多個檔案或者目錄

     * @param filePathList

     * @throws Exception

    public static void zip(ArrayList<String> filePathList , String zipFilePath) throws Exception{

         System.out.println("壓縮中...");

         ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFilePath));  

         BufferedOutputStream bo = new BufferedOutputStream(out); 

         if(filePathList==null || filePathList.size()==0){

             throw new RuntimeException("沒有指定需要壓縮的檔案");

         for(String filePath :filePathList){

             File srcFile = new File(filePath);

             zip(out, srcFile, srcFile.getName(), bo); 

         System.out.println("壓縮完成"); 

    private static void zip(ZipOutputStream out , File srcFile ,String base ,BufferedOutputStream bo) throws Exception{

        //如果需要壓縮的檔案是目錄,則進行遞歸壓縮處理

        if(srcFile.isDirectory()){

            File[] fileList = srcFile.listFiles();  

            //如果是空目錄,也需要将該目錄壓縮進去,注意,此時zipentry的name必須以“/"結束

            if (fileList.length == 0) {  

                out.putNextEntry(new ZipEntry(base + "/")); // 建立zip壓縮進入點base  

                out.closeEntry();

            }  

            for (int i = 0; i < fileList.length; i++) {  

                zip(out, fileList[i], base + "/" + fileList[i].getName(), bo); // 遞歸周遊子檔案夾  

            } 

        }

        else{

            out.putNextEntry(new ZipEntry(base)); // 建立zip壓縮進入點base  

            FileInputStream in = new FileInputStream(srcFile);  

            byte[]buffer = new byte[1024];

            int len = 0;

            while((len = in.read(buffer))!=-1){

                out.write(buffer ,0 ,len);

            }  

            in.close(); // 輸入流關閉 

    } 

http://www.cnblogs.com/itmanxgl/p/84db9a95b5d84643580678994f6488b4.html