首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android 大文件解壓優化實戰:使用 ZipInputStream 分塊讀寫控制內存佔用

     編輯:程式設計疑難解答

問題背景

電子書項目需解壓 EPUB 文件(本質是 ZIP),大文件解壓後內存飆升 40MB+,易導致 OOM。

優化核心:流式處理 + 固定緩衝區

不將整個解壓內容載入內存,而是邊讀邊寫,使用固定大小 byte 數組(如 1MB)作為緩衝區。

完整工具方法

public static void unZip(Context context, String assetName, String outputDirectory) throws IOException {
    File srcFile = new File(FileTools.getStoragePath(context, false) + "/" + assetName);
    File destDir = new File(outputDirectory);
    if (!destDir.exists()) destDir.mkdirs();

    try (FileInputStream fis = new FileInputStream(srcFile);
         ZipInputStream zis = new ZipInputStream(fis)) {

        byte[] buffer = new byte[1024 * 1024]; // 1MB 緩衝區
        ZipEntry entry;
        while ((entry = zis.getNextEntry()) != null) {
            File outFile = new File(destDir, entry.getName());
            if (entry.isDirectory()) {
                outFile.mkdirs();
            } else {
                outFile.getParentFile().mkdirs(); // 確保父目錄存在
                try (FileOutputStream fos = new FileOutputStream(outFile)) {
                    int len;
                    while ((len = zis.read(buffer)) > 0) {
                        fos.write(buffer, 0, len);
                    }
                }
            }
            zis.closeEntry();
        }
    }
}

關鍵點解析

  1. ZipInputStream:逐個讀取 ZIP 條目,不載入中央目錄到內存。
  2. 1MB 緩衝區:平衡 I/O 次數與內存佔用,可根據設備調整(如 64KB-4MB)。
  3. try-with-resources:自動關閉流,防止泄漏。
  4. 目錄創建:getParentFile().mkdirs() 確保嵌套目錄存在。

進階優化

  • 大文件可考慮 RandomAccessFile + 多線程分段解壓。
  • 解壓進度回調:在循環中計算已處理字節數 / 總大小更新 UI。
  • 校驗完整性:解壓後比對 CRC32 或文件大小。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved