简体   繁体   中英

Opening password protected RAR files in Java

I've been searching Google for some time now but can't seem to find any library that allows me to open password protected RAR files using Java (compressed files).

If anyone knows of one please share it with me (if possible one including a maven dependency).

I've been looking at JUnRar and java-UnRar, but both do not support password protected files for as far as I could discover.

WinRAR is shipped with two utility programs (unrar.exe and rar.exe). From Powershell, you can unrar an archive by calling: unrar e .\\my-archive.rar -p[your-password]

Now, you could place this call using the exec() method of Java's Runtime class:

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

However, this option has some drawbacks:

  • Password is handled as string (bad practice when handling password)

  • I do not know how exec() is implemented for Windows JVMs. I think there is a risk the password ends up in an unsafe place (log file?) where it does not belong.

  • For me, exec() always has a smell to it (because it introduces coupling to the environment - in this case unrar.exe that is not visible on first glance for later maintainers of your code)

  • You introduce a platform dependency (in this case to Windows) as unrar.exe can run only on Windows (thanks @SapuSeven)

Note: When searching on Stackoverflow.com, you probably stumbled over the Junrar library. It cannot be used to extract encrypted archives (see line 122 of this file ).

SevenZip library could extract many types of archive files including 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()));
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM