java解壓zip,解決編碼和亂碼問題

 pom包


		<dependency>
			<groupId>net.lingala.zip4j</groupId>
			<artifactId>zip4j</artifactId>
			<version>1.3.2</version>
		</dependency>
package com.multek.ebuy.utils;

import net.lingala.zip4j.model.FileHeader;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

//import net.lingala.zip4j.core.ZipFile;
//import net.lingala.zip4j.model.FileHeader;

/**
 * @Author: 徐
 * @Date: 2019/4/19 下午5:00
 * @Description:
 */
public class ZipUtil {

    /**
     * 解壓
     * @param zipPath
     * @param descDir
     * @return
     */
    public static boolean decompressZip(String zipPath, String descDir) {
        File zipFile = new File(zipPath);
        boolean flag = false;
        File pathFile = new File(descDir);
        if (!pathFile.exists()) {
            pathFile.mkdirs();
        }
        ZipFile zip = null;
        try {
            System.setProperty("sun.zip.encoding", System.getProperty("sun.jnu.encoding"));
//            zip = new ZipFile(zipFile, Charset.forName("UTF-8"));//防止中文目錄,亂碼
            String encoding = getEncoding(zipPath);
            zip = new ZipFile(zipFile, Charset.forName(encoding));//防止中文目錄,亂碼
            for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
                String zipEntryName = entry.getName();
                InputStream in = zip.getInputStream(entry);
                //指定解壓後的文件夾+當前zip文件的名稱
                String outPath = (descDir + "/" + zipEntryName).replace("/", File.separator);
                //判斷路徑是否存在,不存在則創建文件路徑
                File file = new File(outPath.substring(0, outPath.lastIndexOf(File.separator)));
                if (!file.exists()) {
                    file.mkdirs();
                }
                //判斷文件全路徑是否爲文件夾,如果是上面已經上傳,不需要解壓
                if (new File(outPath).isDirectory()) {
                    continue;
                }
                //保存文件路徑信息(可利用md5.zip名稱的唯一性,來判斷是否已經解壓)
                OutputStream out = new FileOutputStream(outPath);
                byte[] buf1 = new byte[2048];
                int len;
                while ((len = in.read(buf1)) > 0) {
                    out.write(buf1, 0, len);
                }
                in.close();
                out.close();
            }
            flag = true;
            //必須關閉,要不然這個zip文件一直被佔用着,要刪刪不掉,改名也不可以,移動也不行,整多了,系統還崩了。
            zip.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

//    public static void decompressZip(String source, String target, String targetName) throws Exception {
//        try {
//            File file = new File(source);
//            if (!file.exists() || file.isDirectory()) {
//                throw new Exception("將要解壓文件不存在或路徑不正確!");
//            }
//
//            file = new File(target + File.separator + targetName);
//            if (!file.exists()) {
//                file.mkdirs();
//            }
//            ZipFile zipfile = new ZipFile(source);
//            if (!zipfile.isValidZipFile()) {
//                throw new Exception("壓縮文件不合法,可能被損壞.");
//            }
//            zipfile.setFileNameCharset("UTF-8");
////            zipfile.setFileNameCharset("GBK");
//            zipfile.extractAll(target + File.separator + targetName);
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw e;
//        }
//
//
//    }

//    public static void unZip(String zipPath, String destDir) throws Exception {
//        ZipFile zipFile = new ZipFile(zipPath);
//        zipFile.setFileNameCharset(getEncoding(zipPath));
//        zipFile.extractAll(destDir);
//    }

    @SuppressWarnings("unchecked")
    private static String getEncoding(String path) throws Exception {
        String encoding = "GBK";
        net.lingala.zip4j.core.ZipFile zipFile = new net.lingala.zip4j.core.ZipFile(path);
        zipFile.setFileNameCharset(encoding);
        List<FileHeader> list = zipFile.getFileHeaders();
        for (int i = 0; i < list.size(); i++) {
            FileHeader fileHeader = list.get(i);
            String fileName = fileHeader.getFileName();
            if (isMessyCode(fileName)) {
                encoding = "UTF-8";
                break;
            }
        }
        return encoding;
    }

    private static boolean isMessyCode(String str) {
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            // 當從Unicode編碼向某個字符集轉換時,如果在該字符集中沒有對應的編碼,則得到0x3f(即問號字符?)
            // 從其他字符集向Unicode編碼轉換時,如果這個二進制數在該字符集中沒有標識任何的字符,則得到的結果是0xfffd
            if ((int) c == 0xfffd) {
                // 存在亂碼
                return true;
            }
        }
        return false;
    }


}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章