讨论广场 问答详情
关于鸿蒙开发的zip文件解压缩教程?
qq_84736295 2025-07-24 09:57:23
152 评论 分享

关于鸿蒙开发的zip文件解压缩教程?

152 评论 分享
写回答
全部评论(1)

在鸿蒙开发中,可使用鸿蒙系统提供的ZipFileZipEntry等 API 实现 ZIP 文件的解压缩功能。以下是具体实现步骤和示例:

"requestPermissions": [
  {
    "name": "ohos.permission.READ_USER_STORAGE"
  },
  {
    "name": "ohos.permission.WRITE_USER_STORAGE"
  }
]

(API 10 + 可使用更精细的媒体文件权限,如ohos.permission.READ_MEDIA

二、解压缩核心代码实现

import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.Resource;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.utils.zigzag.ZigZag;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class ZipUtils {
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "ZipUtils");
    private static final int BUFFER_SIZE = 8192;

    /**
     * 解压ZIP文件到指定目录
     * @param context 上下文
     * @param zipFilePath ZIP文件路径(如沙箱路径:Context.getFilesDir() + "/test.zip")
     * @param destDir 解压目标目录
     * @return 是否解压成功
     */
    public static boolean unzip(Context context, String zipFilePath, String destDir) {
        File destDirectory = new File(destDir);
        if (!destDirectory.exists()) {
            if (!destDirectory.mkdirs()) {
                HiLog.error(LABEL, "创建解压目录失败");
                return false;
            }
        }

        try (ZipFile zipFile = new ZipFile(zipFilePath)) {
            // 遍历ZIP中的所有条目
            zipFile.stream().forEach(entry -> {
                try {
                    unzipEntry(zipFile, entry, destDir);
                } catch (IOException e) {
                    HiLog.error(LABEL, "解压条目失败: %{public}s", e.getMessage());
                }
            });
            return true;
        } catch (IOException e) {
            HiLog.error(LABEL, "解压ZIP文件失败: %{public}s", e.getMessage());
            return false;
        }
    }

    /**
     * 解压单个ZIP条目
     */
    private static void unzipEntry(ZipFile zipFile, ZipEntry entry, String destDir) throws IOException {
        String entryName = entry.getName();
        File entryFile = new File(destDir, entryName);

        // 若为目录,创建文件夹
        if (entry.isDirectory()) {
            if (!entryFile.exists() && !entryFile.mkdirs()) {
                throw new IOException("创建目录失败: " + entryFile.getAbsolutePath());
            }
            return;
        }

        // 确保父目录存在
        File parentDir = entryFile.getParentFile();
        if (!parentDir.exists() && !parentDir.mkdirs()) {
            throw new IOException("创建父目录失败: " + parentDir.getAbsolutePath());
        }

        // 读取ZIP条目内容并写入文件
        try (InputStream in = zipFile.getInputStream(entry);
             OutputStream out = new FileOutputStream(entryFile)) {

            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
        }
    }

    /**
     * 从应用资源(raw目录)中解压ZIP文件
     * @param context 上下文
     * @param resourceId 资源ID(如:ResourceTable.Raw_test_zip)
     * @param destDir 解压目标目录
     */
    public static boolean unzipFromResource(Context context, int resourceId, String destDir) {
        try (Resource resource = context.getResourceManager().getResource(resourceId);
             InputStream inputStream = resource.openRawStream()) {

            // 先将资源文件复制到沙箱路径
            String tempZipPath = context.getFilesDir() + "/temp.zip";
            try (OutputStream outputStream = new FileOutputStream(tempZipPath)) {
                byte[] buffer = new byte[BUFFER_SIZE];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
            }

            // 解压临时文件
            return unzip(context, tempZipPath, destDir);
        } catch (IOException | NotExistException e) {
            HiLog.error(LABEL, "从资源解压失败: %{public}s", e.getMessage());
            return false;
        }
    }
}

三、使用示例

// 1. 解压沙箱中的ZIP文件
String zipPath = getContext().getFilesDir() + "/books.zip"; // ZIP文件路径
String destPath = getContext().getFilesDir() + "/unzipped_books"; // 解压目标路径
boolean result = ZipUtils.unzip(getContext(), zipPath, destPath);

// 2. 解压应用raw目录中的ZIP资源(如预先打包的书籍、配置文件)
boolean resResult = ZipUtils.unzipFromResource(getContext(), ResourceTable.Raw_books, destPath);

四、关键说明

 

通过以上方法,可实现 ZIP 文件的解压缩,适用于电子书资源解压、配置文件提取等场景。

  1. 文件路径处理
    鸿蒙应用有严格的沙箱机制,建议将 ZIP 文件和解压目录放在应用沙箱内(如context.getFilesDir()context.getCacheDir()),避免权限问题。

  2. 大文件处理
    解压缩可能耗时,需在后台线程(如TaskDispatcher)中执行,避免阻塞 UI:

    getGlobalTaskDispatcher(TaskPriority.DEFAULT).asyncDispatch(() -> {
        ZipUtils.unzip(getContext(), zipPath, destPath);
    });

     

  3. 异常处理
    需处理文件不存在、权限不足、ZIP 文件损坏等异常,通过HiLog输出日志便于调试。

  4. API 兼容性
    上述代码基于 Java API,适用于鸿蒙 Next 及 API 9 + 版本,若使用 ArkTS,可通过@ohos.zip模块实现类似功能(语法略有差异)。


  5.  

 

 

 

 

2025-08-07 18:02:25