| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- 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<FileHeader>)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<? extends ZipEntry> 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;
- }
- }
- }
|