1. 程式人生 > >Java壓縮技術(二) ZIP壓縮——Java原生實現

Java壓縮技術(二) ZIP壓縮——Java原生實現

查過相關資料後才知道,ZIP應該算作歸檔類的壓縮演算法,每一門學科都可深可淺!

閒言少敘,先說ZIP壓縮。 
zip壓縮需要通過ZipOutputStream 執行write方法將壓縮資料寫到指定輸出流中。 
注意,這裡應先使用CheckedOutputStream 指定檔案校驗演算法。(通常使用CRC32演算法)。程式碼如下所示: 
Java程式碼  收藏程式碼
  1. CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(destPath), new CRC32());  
  2. ZipOutputStream zos = new
     ZipOutputStream(cos);  

接下來,需要將待壓縮檔案以ZipEntry的方式追加到壓縮檔案中,如下所示: 
Java程式碼  收藏程式碼
  1.  /** 
  2.  * 壓縮包內檔名定義 
  3.  *  
  4.  * <pre> 
  5.  * 如果有多級目錄,那麼這裡就需要給出包含目錄的檔名 
  6.  * 如果用WinRAR開啟壓縮包,中文名將顯示為亂碼 
  7.  * </pre> 
  8.  */  
  9. ZipEntry entry = new ZipEntry(dir + file.getName());  
  10. zos.putNextEntry(entry);  

ZipEntry就是壓縮包中的每一個實體! 

完成上述準備後,就可以執行壓縮操作了。實際上,就是執行ZipOutputStream類的write方法,如下所示: 
Java程式碼  收藏程式碼
  1. BufferedInputStream bis = new BufferedInputStream(new FileInputStream(  
  2.         file));  
  3. int count;  
  4. byte data[] = new byte[BUFFER];  
  5. while ((count = bis.read(data, 0, BUFFER)) != -1) {  
  6.     zos.write(data, 0, count);  
  7. }  
  8. bis.close();  

當然,如果待新增的壓縮項是一個目錄。那麼,需要通過遞迴的方式指定最終的壓縮項。 
如果要新增一個空目錄,注意使用符號"/"(String PATH="/";)作為新增項名字結尾符!

遞迴構建目錄壓縮,程式碼如下: 
Java程式碼  收藏程式碼
  1. /** 
  2.  * 壓縮 
  3.  *  
  4.  * @param srcFile 
  5.  *            源路徑 
  6.  * @param zos 
  7.  *            ZipOutputStream 
  8.  * @param basePath 
  9.  *            壓縮包內相對路徑 
  10.  * @throws Exception 
  11.  */  
  12. private static void compress(File srcFile, ZipOutputStream zos,  
  13.         String basePath) throws Exception {  
  14.     if (srcFile.isDirectory()) {  
  15.         compressDir(srcFile, zos, basePath);  
  16.     } else {  
  17.         compressFile(srcFile, zos, basePath);  
  18.     }  
  19. }  
  20. /** 
  21.  * 壓縮目錄 
  22.  *  
  23.  * @param dir 
  24.  * @param zos 
  25.  * @param basePath 
  26.  * @throws Exception 
  27.  */  
  28. private static void compressDir(File dir, ZipOutputStream zos,  
  29.         String basePath) throws Exception {  
  30.     File[] files = dir.listFiles();  
  31.     // 構建空目錄  
  32.     if (files.length < 1) {  
  33.         ZipEntry entry = new ZipEntry(basePath + dir.getName() + PATH);  
  34.         zos.putNextEntry(entry);  
  35.         zos.closeEntry();  
  36.     }  
  37.     for (File file : files) {  
  38.         // 遞迴壓縮  
  39.         compress(file, zos, basePath + dir.getName() + PATH);  
  40.     }  
  41. }  

x是一個空目錄,用WinRAR開啟後,可以看到這個目錄下還有一個空檔名檔案!


來個完整的壓縮實現,程式碼如下所示: 
Java程式碼  收藏程式碼
  1. /** 
  2.  * 2010-4-12 
  3.  */  
  4. package org.zlex.commons.io;  
  5. import java.io.BufferedInputStream;  
  6. import java.io.BufferedOutputStream;  
  7. import java.io.File;  
  8. import java.io.FileInputStream;  
  9. import java.io.FileOutputStream;  
  10. import java.util.zip.CRC32;  
  11. import java.util.zip.CheckedInputStream;  
  12. import java.util.zip.CheckedOutputStream;  
  13. import java.util.zip.ZipEntry;  
  14. import java.util.zip.ZipInputStream;  
  15. import java.util.zip.ZipOutputStream;  
  16. /** 
  17.  * ZIP壓縮工具 
  18.  *  
  19.  * @author  <a href="mailto:[email protected]">樑棟</a>    
  20.  * @since 1.0 
  21.  */  
  22. public class ZipUtils {  
  23.     public static final String EXT = ".zip";  
  24.     private static final String BASE_DIR = "";  
  25.     // 符號"/"用來作為目錄標識判斷符  
  26.     private static final String PATH = "/";  
  27.     private static final int BUFFER = 1024;  
  28.     /** 
  29.      * 壓縮 
  30.      *  
  31.      * @param srcFile 
  32.      * @throws Exception 
  33.      */  
  34.     public static void compress(File srcFile) throws Exception {  
  35.         String name = srcFile.getName();  
  36.         String basePath = srcFile.getParent();  
  37.         String destPath = basePath + name + EXT;  
  38.         compress(srcFile, destPath);  
  39.     }  
  40.     /** 
  41.      * 壓縮 
  42.      *  
  43.      * @param srcFile 
  44.      *            源路徑 
  45.      * @param destPath 
  46.      *            目標路徑 
  47.      * @throws Exception 
  48.      */  
  49.     public static void compress(File srcFile, File destFile) throws Exception {  
  50.         // 對輸出檔案做CRC32校驗  
  51.         CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(  
  52.                 destFile), new CRC32());  
  53.         ZipOutputStream zos = new ZipOutputStream(cos);  
  54.         compress(srcFile, zos, BASE_DIR);  
  55.         zos.flush();  
  56.         zos.close();  
  57.     }  
  58.     /** 
  59.      * 壓縮檔案 
  60.      *  
  61.      * @param srcFile 
  62.      * @param destPath 
  63.      * @throws Exception 
  64.      */  
  65.     public static void compress(File srcFile, String destPath) throws Exception {  
  66.         compress(srcFile, new File(destPath));  
  67.     }  
  68.     /** 
  69.      * 壓縮 
  70.      *  
  71.      * @param srcFile 
  72.      *            源路徑 
  73.      * @param zos 
  74.      *            ZipOutputStream 
  75.      * @param basePath 
  76.      *            壓縮包內相對路徑 
  77.      * @throws Exception 
  78.      */  
  79.     private static void compress(File srcFile, ZipOutputStream zos,  
  80.             String basePath) throws Exception {  
  81.         if (srcFile.isDirectory()) {  
  82.             compressDir(srcFile, zos, basePath);  
  83.         } else {  
  84.             compressFile(srcFile, zos, basePath);  
  85.         }  
  86.     }  
  87.     /** 
  88.      * 壓縮 
  89.      *  
  90.      * @param srcPath 
  91.      * @throws Exception 
  92.      */  
  93.     public static void compress(String srcPath) throws Exception {  
  94.         File srcFile = new File(srcPath);  
  95.         compress(srcFile);  
  96.     }  
  97.     /** 
  98.      * 檔案壓縮 
  99.      *  
  100.      * @param srcPath 
  101.      *            原始檔路徑 
  102.      * @param destPath 
  103.      *            目標檔案路徑 
  104.      *  
  105.      */  
  106.     public static void compress(String srcPath, String destPath)  
  107.             throws Exception {  
  108.         File srcFile = new File(srcPath);  
  109.         compress(srcFile, destPath);  
  110.     }  
  111.     /** 
  112.      * 壓縮目錄 
  113.      *  
  114.      * @param dir 
  115.      * @param zos 
  116.      * @param basePath 
  117.      * @throws Exception 
  118.      */  
  119.     private static void compressDir(File dir, ZipOutputStream zos,  
  120.             String basePath) throws Exception {  
  121. 相關推薦

    Java壓縮技術 ZIP壓縮——Java原生實現

    查過相關資料後才知道,ZIP應該算作歸檔類的壓縮演算法,每一門學科都可深可淺!閒言少敘,先說ZIP壓縮。 zip壓縮需要通過ZipOutputStream 執行write方法將壓縮資料寫到指定輸出流中。 注意,這裡應先使用CheckedOutputStream 指定檔案校驗

    Java壓縮技術 ZLib

    有關ZLib可參見官方主頁 http://www.zlib.net/ZLib可以簡單的理解為壓縮/解壓縮演算法,它與ZIP、RAR等歸檔演算法有所不同,與bzip2比較接近。 壓縮工具程式碼如下:  Java程式碼   /**   * 2009-9-9   */  

    10.2-全棧Java筆記:最全面的IO技術

    java上節我們聊到「IO技術概念及入門」這節我們繼續聊一下IO技術的分類。Java中流的概念細分按流的方向分類:輸入流:數據流向是數據源到程序(InputStream、Reader結尾的流)輸出流:數據流向是程序到目的地(OutPutStream、Writer結尾的流)按處理的數據單元:字節流:按照字節讀取

    淺談存儲重刪壓縮技術

    emc 將他 壓力測試 處理方式 比對 公眾號 center str 今天 淺談重刪壓縮技術(一) <喜歡更多內容可以關註微信公眾號“圍爐煮酒論IT”>作為一個做企業存儲市場的存儲人,最近兩年我不斷被重刪壓縮撩撥著。對於重刪壓縮這個技術的好壞,真實需求還是偽需求

    PDF技術-Java實現Txt轉PDF檔案

    TxT轉PDF可以直接使用IText就可以了,IText在pdf領域可以說暫時是最好的方案了。通過直接讀取txt檔案,然後生成pdf,再新增文字就可以了。 1)使用IText實現轉換 原理: 使用IText建立pdf,新增文字。 優點: 速度快。 缺點: 具體實現:

    速度之王 — LZ4壓縮演算法

    LZ4 (Extremely Fast Compression algorithm) 作者:Yann Collet 本文作者:zhangskd @ csdn blog LZ4格式 The compressed block is composed of sequence

    淺談壓縮感知:理論基礎

    主要內容: 訊號的稀疏表示編碼測量(取樣過程)恢復演算法(非線性)一、訊號與影象的稀疏表示 在DSP(數字訊號處理)中,有個很重要的概念:變換域(某個線性空間:一組基函式支撐起來的空間) 一般而言,我們的訊號都是在時域或空域中來表示,其實我們可以在其他變換域中通過某些正交基函式的線性組合來表示訊號。如:si

    java解析xml技術

    在上一篇java解析xml技術(一)中,我已經講完jdk中自帶解析xml的兩種方式dom和sax,現在我繼續講一講另一個java平臺下的xml解析工具dom4j。 dom4j就是dom for jav

    java學習筆記圖形用戶接口

    star strong per getwidth cep runnable graphics s2d gb2 這個學期主要放在ACM比賽上去了,比賽結束了。不知不覺就15周了,這周就要java考試了,復習一下java吧。java的學習的目的還是讓我們學以致用,讓我們可以

    照相機技術

    nac ddc dmi nbsp stop eas 大小 aced htm 1 //定制拍照: 2 public class MainActivity extends Activity { 3 private Camera mCamera; 4

    Java加密技術——BASE64與單向加密算法MD5&SHA&MAC

    sha256 integer 被人 sent 發現 Coding design 如果 targe http://snowolf.iteye.com/blog/379860 加密解密,曾經是我一個畢業設計的重要組件。在工作了多年以後回想當時那個加密、解密算法,實在是太單

    JAVA 內部類

    匿名內部類 獨立 button strong 知識 desc ets .get xxx 一、為什麽要使用內部類 為什麽要使用內部類?在《Think in java》中有這樣一句話:使用內部類最吸引人的原因是:每個內部類都能獨立地繼承一個(接口的)實現,所以無論外

    java設計模式工廠模式

    額外 mod 通過反射 pat 擴展 簡單實現 需要 factory actor   工廠模式是最常見的實例化對象的模式,用來替代new操作。采用這種模式創建對象會有一些額外的操作,但他會帶給系統更大的擴展性和更少的修改量。典型的應用spring bean容器。下面簡單實現

    java面試題

    imap 產生 java面試 大型 過程 ets ibm apache服務 廣泛 11、說出Servlet的生命周期,並說出Servlet和CGI的區別? Servlet被服務器實例化後,容器運行其init方法,請求到達時運行其service方法,service方法自動派遣

    Java學習筆記-------String,StringBuffer,StringBuilder區別以及映射到的同步,異步相關知識

    ringbuf 等待 java學習筆記 java學習 單線程 回復 改變 hashtable ble 1. String是不可變類,改變String變量中的值,相當於開辟了新的空間存放新的string變量 2. StringBuffer 可變的類,可以通過append方法改

    Java包(package)

    net clas 控制 組織 容易 存儲方式 它的 如同 true 為了更好地組織類,Java 提供了包機制,用於區別類名的命名空間。 一個包(package)可以定義為一組相互聯系的類型(類、接口、枚舉和註釋) 使用包這種機制,更容易實現訪問控制,並且讓定位相關類更加簡單

    Java加密技術——數字證書

    keystore 表示 encode png 代碼 簽名 更新 rsa加密 turn 原文:http://snowolf.iteye.com/blog/391931 請大家在閱讀本篇內容時先閱讀 Java加密技術(四),預先了解RSA加密算法。 在構建Java代碼實現前

    Java語法糖

    version rgs tab uip class a void 文件名 私有 tail 語法糖之四:內部類   內部類:顧名思義,在類的內部在定義一個類。內部類僅僅是編譯時的概念,編譯成字節碼後,內部類會生成單獨的Class文件。   四種:成員內部類、局部內部類、匿名內

    java基礎總結---關鍵字

    -- rem 關鍵字 rgs java err style ret 基礎總結 1.this   在java中, this 對象,它可以在類裏面來引用這個類的屬性和方法。   1.它在方法內部使用,即這個方法所屬的對象的引用。   2.它在構造器內部使用,表示該構造器正在初始

    深度學習的異構加速技術:螺獅殼裏做道場

    篩選 分享 intel 支持 get 更多 wid efficient 優勢 作者簡介:kevinxiaoyu,高級研究員,隸屬騰訊TEG-架構平臺部,主要研究方向為深度學習異構計算與硬件加速、FPGA雲、高速視覺感知等方向的構架設計和優化。“深度學習的異構加速技術”系列