解壓RAR5

如下內容來自《WinRAR.chm》"RAR5"java

是 WinRAR 5.0 引入的最新版本的 RAR 格式。它包含不少重要的修改,如 AES-256 加密、更有效的恢復記錄、更大的字典大小,較老的軟件,包括老版本的 WinRAR,不能解壓 RAR 5.0 壓縮文件。因此若是你計劃把一個壓縮文件發送給其餘人,選擇 RAR5 須要考慮兼容性問題。

RAR5加密算法並未公佈,因此不少開源工具包都只支持rar4,在解壓rar5格式時,會報出不支持rar5格式的錯誤,好比經常使用的junaralinux

PLAN A

通過仔細的翻閱Google,找到了這個: http://sevenzipjbind.sourcefo...c++

7-Zip-JBinding is a java wrapper for 7-Zip C++ library. It allows extraction of many archive formats using a very fast native library directly from java through JNI. Features:

簡而言之,7-Zip-JBinding 是一個c++版7-Zip的封裝,就和在你本地安裝了7-Zip是相似的效果,經過jni交互。算法

官網有更詳細的介紹,和一些簡單的例子:windows

<dependency>
    <groupId>net.sf.sevenzipjbinding</groupId>
    <artifactId>sevenzipjbinding</artifactId>
    <version>16.02-2.01</version>
</dependency>
<dependency>
    <groupId>net.sf.sevenzipjbinding</groupId>
    <artifactId>sevenzipjbinding-all-platforms</artifactId>
    <version>16.02-2.01</version>
</dependency>


private int getNumberOfItemsInArchive(String archiveFile) throws Exception {
    IInArchive archive;
    RandomAccessFile randomAccessFile;

    randomAccessFile = new RandomAccessFile(archiveFile, "r");

    archive = SevenZip.openInArchive(ArchiveFormat.ZIP, // null - autodetect
            new RandomAccessFileInStream(randomAccessFile));

    int numberOfItems = archive.getNumberOfItems();

    archive.close();
    randomAccessFile.close();

    return numberOfItems;
}

通過實測,這種方式是能夠實現解壓rar5的,可是還有一些問題,因爲文件編碼問題,可能會出現解壓出的文件存在亂碼的狀況。這種狀況暫時不知道怎麼處理,API上沒有相關參數能夠指定文件編碼bash

PLAN B

既然RAR5沒公佈算法,那咱們就本身破解,肝出來!app

......運維

開個玩笑dom

緊接着我換了一種思路,代碼不行,工具來湊,找到了這個: http://www.rarlab.com工具

Welcome to RARLAB, home of WinRAR and RAR archivers

這個描述就很舒服

支持windows、linux、mac(我在mac用的就是這個命令,當時找了好幾個解壓rar的軟件都要付費,索性brew install rar)

咱們能夠在代碼裏調用系統腳本,來達到解壓rar的目的

先來安裝一下

uname -a 
# 根據系統位數選擇對應的包
wget https://www.rarlab.com/rar/rarlinux-x64-6.0.2b1.tar.gz
# wget https://www.rarlab.com/rar/rarlinux-6.0.2b1.tar.gz
tar -zxvf rarlinux-x64-6.0.2b1.tar.gz
cd rar
make & make install

若是你沒有權限的話,能夠找運維同窗幫助

public class UnrarUtils {
    private static final Logger LOG = LoggerFactory.getLogger(UnrarUtils.class);
    private static final String UNRAR_CMD = "unrar x ";
    /**
     * 將1個RAR文件解壓
     * rarFileName 須要解壓的RAR文件(必須包含路徑信息以及後綴)
     * destDir 解壓後的文件放置目錄
     */
    public static String unRARFile(String filepath) {
        String name = filepath.substring(0, filepath.lastIndexOf('.'));
        File targetDir = new File(name);
        if (!targetDir.exists()) {
            targetDir.mkdirs();
        }
        String cmd = UNRAR_CMD + filepath + " " + name;
        try {
            Runtime rt = Runtime.getRuntime();
            Process process = rt.exec(cmd);
            int retCode = process.waitFor();
            if (retCode == 0) {
                LOG.info("解壓完畢");
                return name;
            }
        } catch (Exception e) {
            LOG.warn("解壓rar文件失敗:{}", JSONObject.toJSONString(e));
        }
        return name;
    }
}

注意:process.waitFor() 會阻塞主線程,同時新開一個子線程去執行任務,若是任務耗時的話, 可能會引發一些其餘的問題。

固然本例中,waitFor的做用是,等待解壓完畢,會去讀取目錄下的文件,若是不等它的話,就讀不到你想要的文件了。

以上就是本次所有內容了,感謝閱讀。

相關文章
相關標籤/搜索