17

我正在寻找一种.rar使用 Java 解压缩文件的方法,并且无论我在哪里搜索,我都会一直使用相同的工具 - JavaUnRar. 我一直在研究.rar用这个解压缩文件,但我似乎找到的所有方法都很长而且很尴尬,就像在这个例子中一样

我目前能够在 20 行或更少的代码中提取.tar、和文件.tar.gz,因此必须有一种更简单的方法来提取文件,有人知道吗?.zip.jar.rar

只要它对任何人都有帮助,这是我用来提取.zip.jar文件的代码,它适用于两者

 public void getZipFiles(String zipFile, String destFolder) throws IOException {
    BufferedOutputStream dest = null;
    ZipInputStream zis = new ZipInputStream(
                                       new BufferedInputStream(
                                             new FileInputStream(zipFile)));
    ZipEntry entry;
    while (( entry = zis.getNextEntry() ) != null) {
        System.out.println( "Extracting: " + entry.getName() );
        int count;
        byte data[] = new byte[BUFFER];

        if (entry.isDirectory()) {
            new File( destFolder + "/" + entry.getName() ).mkdirs();
            continue;
        } else {
            int di = entry.getName().lastIndexOf( '/' );
            if (di != -1) {
                new File( destFolder + "/" + entry.getName()
                                             .substring( 0, di ) ).mkdirs();
            }
        }
        FileOutputStream fos = new FileOutputStream( destFolder + "/"
                                                     + entry.getName() );
        dest = new BufferedOutputStream( fos );
        while (( count = zis.read( data ) ) != -1) 
            dest.write( data, 0, count );
        dest.flush();
        dest.close();
    }
}
4

4 回答 4

21

您可以提取.gz, .zip,.jar文件,因为它们使用 Java SDK 中内置的多种压缩算法。

RAR格式的情况有点不同。RAR 是一种专有的存档文件格式。RAR 许可证不允许将其包含在 Java SDK 等软件开发工具中。

解压缩文件的最佳方法是使用 junrar 等 3rd 方

您可以在 SO question RAR archives with java中找到对其他 Java RAR 库的一些引用。SO问题How to compress text file to rar format using java program解释了更多不同的解决方法(例如使用Runtime)。

于 2013-01-12T01:33:07.253 回答
2

你可以使用图书馆junrar

<dependency>
   <groupId>com.github.junrar</groupId>
   <artifactId>junrar</artifactId>
   <version>0.7</version>
</dependency>

代码示例:

            File f = new File(filename);
            Archive archive = new Archive(f);
            archive.getMainHeader().print();
            FileHeader fh = archive.nextFileHeader();
            while(fh!=null){        
                    File fileEntry = new File(fh.getFileNameString().trim());
                    System.out.println(fileEntry.getAbsolutePath());
                    FileOutputStream os = new FileOutputStream(fileEntry);
                    archive.extractFile(fh, os);
                    os.close();
                    fh=archive.nextFileHeader();
            }
于 2019-03-19T20:55:36.310 回答
1

您可以简单地将这个 Maven 依赖项添加到您的代码中:

<dependency>
    <groupId>com.github.junrar</groupId>
    <artifactId>junrar</artifactId>
    <version>0.7</version>
</dependency>

然后使用此代码提取 rar 文件:

        File rar = new File("path_to_rar_file.rar");
    File tmpDir = File.createTempFile("bip.",".unrar");
    if(!(tmpDir.delete())){
        throw new IOException("Could not delete temp file: " + tmpDir.getAbsolutePath());
    }
    if(!(tmpDir.mkdir())){
        throw new IOException("Could not create temp directory: " + tmpDir.getAbsolutePath());
    }
    System.out.println("tmpDir="+tmpDir.getAbsolutePath());
    ExtractArchive extractArchive = new ExtractArchive();
    extractArchive.extractArchive(rar, tmpDir);
    System.out.println("finished.");
于 2018-04-19T06:21:45.547 回答
0

您可以使用http://sevenzipjbind.sourceforge.net/index.html

除了支持大量存档格式外,16.02-2.01 版本还完全支持 RAR5 提取:

  • 受密码保护的档案
  • 带有加密标题的档案
  • 档案分卷

毕业典礼

implementation 'net.sf.sevenzipjbinding:sevenzipjbinding:16.02-2.01'
implementation 'net.sf.sevenzipjbinding:sevenzipjbinding-all-platforms:16.02-2.01'

或行家

<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>

和代码示例


import net.sf.sevenzipjbinding.ExtractOperationResult;
import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * Responsible for unpacking archives with the RAR extension.
 * Support Rar4, Rar4 with password, Rar5, Rar5 with password.
 * Determines the type of archive itself.
 */
public class RarExtractor {

    /**
     * Extracts files from archive. Archive can be encrypted with password
     *
     * @param filePath path to .rar file
     * @param password string password for archive
     * @return map of extracted file with file name
     * @throws IOException
     */
    public Map<InputStream, String> extract(String filePath, String password) throws IOException {
        Map<InputStream, String> extractedMap = new HashMap<>();

        RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "r");
        RandomAccessFileInStream randomAccessFileStream = new RandomAccessFileInStream(randomAccessFile);
        IInArchive inArchive = SevenZip.openInArchive(null, randomAccessFileStream);

        for (ISimpleInArchiveItem item : inArchive.getSimpleInterface().getArchiveItems()) {
            if (!item.isFolder()) {
                ExtractOperationResult result = item.extractSlow(data -> {
                    extractedMap.put(new BufferedInputStream(new ByteArrayInputStream(data)), item.getPath());

                    return data.length;
                }, password);

                if (result != ExtractOperationResult.OK) {
                    throw new RuntimeException(
                            String.format("Error extracting archive. Extracting error: %s", result));
                }
            }
        }

        return extractedMap;
    }
}

PS @BorisBrodski https://github.com/borisbrodski祝你 40 岁生日快乐!希望你有一个伟大的庆祝活动。感谢您的工作!

于 2020-12-17T10:58:15.780 回答