java壓縮文件解壓:調用WinRAR5命令強於自己寫代碼實現


最近,手上維護着一個幾年前的系統,技術是用的JSP+Strust2,系統提供了rar和zip兩種壓縮格式的解壓功能,后台是用java實現的

1、解壓rar格式,采用的是java-unrar-0.3.jar

2、解壓zip格式,采用的是commons-compress-1.4.1.jar

但最近根據用戶反饋的問題,發現系統存在兩個關於壓縮文件解壓的問題:

1、有些壓縮文件解壓之后出現中文亂碼;

2、有些壓縮文件根本不能解壓

 


 

為了彌補上述兩個問題,在之前代碼的基礎上打了一些補丁,來解決zip壓縮包亂碼的問題,思路大概是:

1、采用GBK編碼解壓

2、遞歸遍歷解壓的文件名是否存在中文亂碼,這用到了網上很常用的中文檢測正則表示式,[\u4e00-\u9fa5]+

3、如果存在中文亂碼,則采用UTF-8編碼解壓

替換后,還是有人反映亂碼問題,煩~~~

第二個問題報錯如下(出現在有些rar格式解壓時):

WARNING: exception in archive constructor maybe file is encrypted or currupt
de.innosystec.unrar.exception.RarException: badRarArchive
    at de.innosystec.unrar.Archive.readHeaders(Archive.java:238)
    at de.innosystec.unrar.Archive.setFile(Archive.java:122)
    at de.innosystec.unrar.Archive.<init>(Archive.java:106)
    at de.innosystec.unrar.Archive.<init>(Archive.java:96)
    at com.reverse.zipFile.CopyOfZipFileUtil.unrar(CopyOfZipFileUtil.java:242)
    at com.reverse.zipFile.CopyOfZipFileUtil.main(CopyOfZipFileUtil.java:303)

 


 

借助百度、谷歌找資料發現:

1、java解壓文件有兩種方式,一是自己寫代碼,二是調用壓縮軟件CMD執行

2、第二個錯誤是由於WinRAR5之后,在rar格式的基礎上,推出了另一種rar,叫RAR5,而java-unrar解析不了這種格式

查看rar格式屬性可以通過右鍵 —> 屬性查看,如圖

因此需要舍棄代碼解壓的方式,改為CMD調用的方式,雖然壓縮軟件有很多,但從網上能找到執行命令的,也就WinRAR了,所以我們采用WinRAR5之后的版本解決,5之前的版本肯定是不行的了

 


 

使用cmd方式效果如何呢?既能解決中文亂碼問題,又能解壓RAR5壓縮文件,而且代碼量還更少了,支持的格式也更多了。

 

附上CMD方式調用代碼:

  /**
     * 采用命令行方式解壓文件
     * @param zipFile 壓縮文件
     * @param destDir 解壓結果路徑
     * @return
     */
    public static boolean realExtract(File zipFile, String destDir) {
        // 解決路徑中存在/..格式的路徑問題
        destDir = new File(destDir).getAbsoluteFile().getAbsolutePath();
        while(destDir.contains("..")) {
            String[] sepList = destDir.split("\\\\");
            destDir = "";
            for (int i = 0; i < sepList.length; i++) {
                if(!"..".equals(sepList[i]) && i < sepList.length -1 && "..".equals(sepList[i+1])) {
                    i++;
                } else {
                    destDir += sepList[i] + File.separator;
                }
            }
        }
        
        // 獲取WinRAR.exe的路徑,放在java web工程下的WebRoot路徑下
        String classPath = "";
        try {
            classPath = Thread.currentThread().getContextClassLoader().getResource("").toURI().getPath();
        } catch (URISyntaxException e1) {
            e1.printStackTrace();
        }
        // 兼容main方法執行和javaweb下執行
        String winrarPath = (classPath.indexOf("WEB-INF") > -1 ? classPath.substring(0, classPath.indexOf("WEB-INF")) :
            classPath.substring(0, classPath.indexOf("classes"))) + "/WinRAR/WinRAR.exe";
        winrarPath = new File(winrarPath).getAbsoluteFile().getAbsolutePath();
        System.out.println(winrarPath);
        
        boolean bool = false;
        if (!zipFile.exists()) {
            return false;
        }
        
        // 開始調用命令行解壓,參數-o+是表示覆蓋的意思
        String cmd = winrarPath + " X -o+ " + zipFile + " " + destDir;
        System.out.println(cmd);
        try {
            Process proc = Runtime.getRuntime().exec(cmd);
            if (proc.waitFor() != 0) {
                if (proc.exitValue() == 0) {
                    bool = false;
                }
            } else {
                bool = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("解壓" + (bool ? "成功" : "失敗"));
        return bool;
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM