天天看點

Android下檔案的壓縮和解壓(Zip格式)

Zip檔案結構

ZIP檔案結構如下圖所示, File Entry表示一個檔案實體,一個壓縮檔案中有多個檔案實體。

檔案實體由一個頭部和檔案資料組,Central Directory由多個File header組成,每個File header都儲存一個檔案實體的偏移,檔案最後由End of central directory結束。

Android下檔案的壓縮和解壓(Zip格式)

用到的類

ZipFile

此類用于從 ZIP 檔案讀取條目ZipEntry,在解壓時用到

ZipEntry

此類用于表示 ZIP 檔案條目

ZipOutputStream

此類為以 ZIP 檔案格式寫入檔案實作輸出流過濾器

Enumeration

實作 Enumeration 接口的對象,它生成一系列元素,一次生成一個。連續調用 nextElement 方法将傳回一系列的連續元素,在解壓縮時會用到

CheckedOutputStream

需要維護寫入資料校驗和的輸出流。校驗和可用于驗證輸出資料的完整性。

CRC32

可用于計算資料流的 CRC-32 的類

壓縮流程

首先要封裝出一個ZipOutputStream: 

Android下檔案的壓縮和解壓(Zip格式)
ZipOutputStream zipOutputStream = new ZipOutputStream(new CheckedOutputStream(new FileOutputStream(file),new CRC32()));           

有了ZipOutputStream後,要壓縮一個檔案,就先在輸出流加入一個ZipEntry,然後擷取需要壓縮的檔案輸入流,然後再輸出:

Android下檔案的壓縮和解壓(Zip格式)

注意最後要重新整理和關閉輸出流

zipOutputStream.flush();
zipOutputStream.close();           

當然這隻是單個檔案的壓縮,我們壓縮檔案時經常會壓縮整個檔案夾,是以還需要周遊整個文檔,針對目錄和檔案分别作出判斷:

Android下檔案的壓縮和解壓(Zip格式)
if (fileSrc.isDirectory()) {
            File[] files = fileSrc.listFiles();

            name = name+"/";
            zipOutputStream.putNextEntry(new ZipEntry(name));  // 建一個檔案夾
            System.out.println("目錄名: "+name);

            for (File f : files) {
                zip(zipOutputStream,name+f.getName(),f);
                System.out.println("目錄: "+name+f.getName());
            }
}           

解壓縮流程

解壓縮就是壓縮的逆過程,其過程就是從壓縮檔案中擷取ZipEntry,擷取其輸入流,将其輸出到指定位置:

Android下檔案的壓縮和解壓(Zip格式)

這也是單個檔案的解壓縮,解壓縮檔案夾隻需周遊ZipFile,判斷ZipEntry是目錄還是檔案,具體操作不再詳解,可到文末的源碼中檢視。

END

本文參考: 

Android 解壓zip檔案你知道多少?

源碼: 

https://github.com/xiaoniu/AndroidZipFile