package com.fdkankan.contro.util; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; import com.fdkankan.contro.constant.ZipConstant; import net.lingala.zip4j.ZipFile; import net.lingala.zip4j.model.FileHeader; import java.io.File; import java.io.InputStream; import java.nio.charset.Charset; import java.nio.file.Paths; import java.util.Enumeration; import java.util.List; import java.util.zip.ZipEntry; public class ZipUtil { public static void main(String[] args) throws Exception { // 压缩包路径 String zipPath = "D:\\Downloads\\各类相机从App导出的原始数据\\bpvt00017_20250314173801715_meta\\bpvt00017_20250314173801715.zip"; System.out.println(readUtf8(zipPath, "data.fdage")); } public static String readUtf8(String zipPath, String fileName) throws Exception { ZipFile zipFile = new ZipFile(zipPath); zipFile.setPassword(ZipConstant.zipPassword.toCharArray()); // 读取所有条目(文件头) for (FileHeader header : (List)zipFile.getFileHeaders()) { // 文件名(不含目录) String filePath = header.getFileName(); String headerFileName = FileUtil.getName(filePath); if (filePath.contains("backup") || !fileName.equals(headerFileName)) { continue; } try (InputStream is = zipFile.getInputStream(header)) { return IoUtil.readUtf8(is); } } return null; } /** * 解压 zip 压缩包到目标目录 * @param zipFilePath 压缩包路径 * @param destDirPath 解压目录 */ public static void unzip(String zipFilePath, String destDirPath) { File zipFile = new File(zipFilePath); File destDir = new File(destDirPath); // 自动检测编码,常见 GBK / UTF-8 Charset charset = detectCharset(zipFile); // 解压(如果是 Windows 打包的 zip,GBK 最常见) cn.hutool.core.util.ZipUtil.unzip(zipFile, destDir, charset); } /** * 检测 ZIP 文件的编码(仅用于文件名编码判断) * 逻辑:UTF-8 -> GBK -> default * @param zipFile ZIP 文件 * @return Charset 识别到的编码 */ public static Charset detectCharset(File zipFile) { // 1. 尝试 UTF-8 if (isCharset(zipFile, Charset.forName("UTF-8"))) { return Charset.forName("UTF-8"); } // 2. 尝试 GBK(Windows zip 默认编码) if (isCharset(zipFile, Charset.forName("GBK"))) { return Charset.forName("GBK"); } // 3. 都不行 → 返回系统默认 return Charset.defaultCharset(); } /** * 判断使用该编码读取 ZIP 是否正常(没有乱码字符) */ private static boolean isCharset(File zipFile, Charset charset) { try (java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFile, charset)) { Enumeration entries = zf.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); // 只检查名字,不读取内容 String name = entry.getName(); // 若名字中出现 �(替换字符),说明编码不对 if (name.contains("\uFFFD")) { return false; } } return true; } catch (Exception e) { // 出现异常说明该编码不匹配 return false; } } }