用Java打开受密码保护的RAR文件

时间:2018-08-14 08:28:55

标签: java

我已经搜索Google一段时间了,但是似乎找不到任何可以使用Java打开受密码保护的RAR文件(压缩文件)的库。

如果有人知道一个,请与我分享(如果可能,包括一个maven依赖项)。

我一直在研究JUnRar和java-UnRar,但据我所知,它们都不支持受密码保护的文件。

2 个答案:

答案 0 :(得分:2)

WinRAR附带了两个实用程序(unrar.exe和rar.exe)。在Powershell中,您可以通过调用unrar e .\my-archive.rar -p[your-password]

来取消存档。

现在,您可以使用Java的Runtime类的exec()方法发出此调用:

public class UnArchiver {

    public static void main(String[] args) {        
        try {   
            String command = "unrar.exe e .\my-archive.rar -pQWERT";
            Runtime.getRuntime().exec(command); 
        } catch (Exception e) {
            e.printStackTrace();
        }   
    }
}
// Code not tested

但是,此选项有一些缺点:

  • 密码被当作字符串处理(处理密码时的错误做法)

  • 我不知道如何为Windows JVM实现exec()。我认为密码可能会被保存在不属于该密码的不安全地方(日志文件?)。

  • 对我来说,exec()总是有一种气味(因为它引入了与环境的耦合-在这种情况下,unrar.exe对于以后的代码维护者而言乍一看不到) )

  • 您引入了平台依赖性(在这种情况下为Windows),因为unrar.exe仅可在Windows上运行(感谢@SapuSeven)

注意:在Stackoverflow.com上搜索时,您可能偶然发现了Junrar库。它不能用于提取加密的存档(请参阅this file的第122行)。

答案 1 :(得分:0)

SevenZip库可以提取许多类型的存档文件,包括RAR

        randomAccessFile= new RandomAccessFile(sourceZipFile, "r");
    inArchive = SevenZip.openInArchive(null, // autodetect archive type
            new RandomAccessFileInStream(randomAccessFile));
    simpleInArchive = inArchive.getSimpleInterface();

    for (int i = 0; i < inArchive.getNumberOfItems(); i++) {
        ISimpleInArchiveItem archiveItem = simpleInArchive.getArchiveItem(i);

        final File outFile = new File(destFolder,archiveItem.getPath());
        outFile.getParentFile().mkdirs();
        logger.debug(String.format("extract(%s) in progress: %s",sourceZipFile.getName(),archiveItem.getPath()));
        final BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(outFile));
        ExtractOperationResult result = archiveItem.extractSlow(new ISequentialOutStream() {
            public int write(byte[] data) throws SevenZipException {
                try {
                    out.write(data);
                } catch (IOException e) {
                    throw new SevenZipException(String.format("error in writing extracted data from:%s to:%s ",sourceZipFile.getName(),outFile.getName()),e);
                }finally{
                    try{out.close();}catch(Exception e){}
                }
                return data.length; // return amount of consumed data
            }
        });
        if(result!=ExtractOperationResult.OK){
            throw new SevenZipException(String.format(" %s error occured in extracting : %s item of file : %s ",result.name(),archiveItem.getPath(),sourceZipFile.getName()));
        }
    }