天天看點

Java壓縮解壓縮檔案

前言

Android應用時時刻刻都應該考慮到為使用者節省流量,消耗流量就是在消耗使用者的金錢,這樣的應用注定沒法得到使用者的青睐。資料壓縮是減少使用者流量的有效方法,現在來使用一下Java内部提供的Zip壓縮實作。

解壓Zip包

Java内部提供了ZipInputStream輸入流專門負責讀取zip類型的檔案,通過ZipInputStream.nextEntry來周遊壓縮包内部所有的資源檔案和檔案夾,在通過讀取解壓縮的資料放到新建立的檔案裡,實作zip包的解壓操作。

在Android6.0以後外部儲存設備的讀寫都需要動态權限申請,之前的Android6.0動态權限申請已經讨論過這個問題,這裡不再給出權限請求代碼。

// 解壓目标目錄
File dir = new File(getExternalCacheDir(), "tomcat");
if (!dir.exists()) {
    dir.mkdir();
}

ZipInputStream zipInputStream = null;
try {
    // 打開assets檔案夾下面的zip包
    zipInputStream = new ZipInputStream(getAssets().open("tomcat.zip"));

    // 周遊zip包裡的ZipEntry對象
    ZipEntry zipEntry = null;
    while ((zipEntry = zipInputStream.getNextEntry()) != null) {
        // 如果是緩存檔案,不做任何處理
        if (zipEntry.getName().startsWith(".")) {
            continue;
        }

        // 如果是檔案夾對象
        if (zipEntry.isDirectory()) {
            // 建立檔案夾對象
            File childDir = new File(dir, zipEntry.getName());
            if (!childDir.exists()) {
                childDir.mkdirs();
            }
        } else {
            // 從zip包中讀取解壓縮的資料,并且拷貝到新建立的解壓檔案裡
            File child = new File(dir, zipEntry.getName());
            FileUtils.copy(zipInputStream, child);
        }
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    IOUtils.close(zipInputStream);
}
           

生成Zip包

生成Zip包相對麻煩一點,需要遞歸的周遊壓縮的檔案夾,同時記錄目前所在檔案路徑位置,確定每個檔案對象都會生成一個ZipEntry對象,但檔案夾不必生成ZipEntry對象。

// 需要壓縮到的檔案夾
File dir = new File(getExternalCacheDir(), "tomcat");
if (!dir.exists()) return;

ZipOutputStream zipOutputStream = null;
try {
    // 生成zip封包件
    File zipFile = new File(getExternalCacheDir(), "ziptomcat.zip");
    if (!zipFile.exists()) {
        zipFile.createNewFile();
    }
    zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFile));

    // 遞歸壓縮檔案夾
    zipDir(dir, zipOutputStream, "");
} catch (IOException e) {
    e.printStackTrace();
} finally {
    IOUtils.close(zipOutputStream);
}

private void zipDir(File dir, ZipOutputStream zipOutputStream, String path) {
    if (dir.isDirectory()) {
        // 如果是檔案夾,壓縮檔案夾,不必為它生成ZipEntry
        for (File file : dir.listFiles()) {
            zipDir(file, zipOutputStream, path + File.separator + dir.getName());
        }
    } else {
        FileInputStream fis = null;
        try {
           // 為目前檔案添加ZipEntry 
           zipOutputStream.putNextEntry(new ZipEntry(path + File.separator + dir.getName()));

          // 拷貝檔案内容到壓縮輸出流裡
            fis = new FileInputStream(dir);
            byte[] bytes = new byte[];
            int count = -;
            while ((count = fis.read(bytes)) != -) {
                zipOutputStream.write(bytes, , count);
            }
            // 結束這個ZipEntry的寫入
            zipOutputStream.closeEntry();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.close(fis);
        }
    }
}
           

繼續閱讀