小小小幸运 发表于 2024-7-30 18:05:03

Java解压rar5兼容rar4

  RAR文件格式由WinRAR开辟,广泛用于文件压缩和归档。随着技术的发展,RAR5作为更新的版本,引入了多项改进以进步压缩效率和数据安全性。

[*]  压缩效率:RAR5通过增大字典大小至32MB,相较于RAR4的4MB,能够更有效地找到数据中的重复模式,从而进步压缩率,特别是在处理大型文件时。
[*]  安全性加强:RAR5采用的256位AES加密算法,提供了更高级别的数据保护,相较于RAR4的加密标准,更难被破解。
[*]  时间戳的国际化:RAR5使用UTC时间,解决了RAR4使用本地时间可能导致的时区混淆问题,使得文件的时间戳在全球范围内保持一致性。
[*]  兼容性考虑:RAR5的格式较新,可能不被旧版本的解压软件识别。在需要确保最大兼容性的场景下,可能仍需使用RAR4格式。
[*]  恢复卷的改进:RAR5格式支持的恢复卷数量大大增加,从RAR4的255个增加到65535个,这在处理多卷压缩文件时提供了更高的灵活性和容错性。
[*]  错误纠正能力:RAR5的恢复记载基于Reed-Solomon错误纠正码,显著进步了压缩文件在受损情况下的自我修复能力。
[*]  日志文件编码:RAR5使用UTF-16小端字节序编码,确保了日志文件中Unicode字符的正确存储和表现,进步了对国际化文件名的支持。
RAR5的Java解压实现
在Java中实现RAR5文件的解压,可以借助java-unrar和SevenZipJBinding库。以下是具体的实现步骤和代码示例。
1、添加依赖:在项目的pom.xml文件中添加相干依赖。
<dependency>
            <groupId>com.github.axet</groupId>
            <artifactId>java-unrar</artifactId>
            <version>1.7.0-8</version>
      </dependency>
      <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>2、编写解压工具类:创建Rar5DocExtractor类,实现解压逻辑。
1 package rar5;
2
3 import net.sf.sevenzipjbinding.*;
4 import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
5
6 import java.io.*;
7 import java.util.*;
8
9 public class Rar5DocExtractor {
10
11   public List<File> extractFiles(File rarFile, File outputDir) throws IOException {
12         Set<File> extractedFiles = new HashSet<>();
13         if (!outputDir.exists()) {
14             outputDir.mkdirs(); // 确保输出目录存在
15         }
16
17         RandomAccessFile randomAccessFile = null;
18         IInArchive inArchive = null;
19         try {
20             randomAccessFile = new RandomAccessFile(rarFile, "r");
21             inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
22             int[] in = new int;
23             for (int i = 0; i < in.length; i++) {
24               in = i;
25             }
26             inArchive.extract(in, false, new ExtractCallback(inArchive, outputDir.getAbsolutePath(), extractedFiles));
27         } finally {
28             if (randomAccessFile != null) {
29               randomAccessFile.close();
30             }
31             if (inArchive != null) {
32               try {
33                     inArchive.close();
34               } catch (SevenZipException e) {
35                     e.printStackTrace();
36               }
37             }
38         }
39         List<File> list=new ArrayList<>(extractedFiles);
40         return list;
41   }
42
43   private static class ExtractCallback implements IArchiveExtractCallback {
44         private IInArchive inArchive;
45         private String outDir;
46         private Set<File> extractedFiles;
47         // 用于跟踪是否需要关闭流的变量
48         private OutputStream fos = null;
49         private boolean closeStreamAfterOperation = false; // 标记流是否需要关闭
50
51         public ExtractCallback(IInArchive inArchive, String outDir, Set<File> extractedFiles) {
52             this.inArchive = inArchive;
53             this.outDir = outDir;
54             this.extractedFiles = extractedFiles;
55         }
56
57         @Override
58         public void setCompleted(long arg0) throws SevenZipException {
59         }
60
61         @Override
62         public void setTotal(long arg0) throws SevenZipException {
63         }
64
65
66         @Override
67         public ISequentialOutStream getStream(int index, ExtractAskMode extractAskMode) throws SevenZipException {
68             final String path = (String) inArchive.getProperty(index, PropID.PATH);
69             // 这里不再创建 File 对象,避免多次调用 getStream 时重复创建
70             return new ISequentialOutStream() {
71               public int write(byte[] data) throws SevenZipException {
72                     File file = new File(outDir, path);
73                     try {
74                         if (data.length == 0) return 0;
75                         file.getParentFile().mkdirs(); // 确保目录存在
76                         if (fos == null) { // 如果这是第一次写入,初始化输出流
77                           fos = new FileOutputStream(file);
78                           closeStreamAfterOperation = true; // 设置标记,表示需要在操作结果后关闭流
79                         }
80                         fos.write(data);
81                         fos.flush(); // 刷新以确保数据被写入磁盘
82                         extractedFiles.add(file); // 添加到提取文件集合
83                     } catch (IOException e) {
84                         throw new SevenZipException("Error writing data to file: " + path, e);
85                     }
86                     return data.length;
87               }
88             };
89         }
90
91         @Override
92         public void prepareOperation(ExtractAskMode arg0) throws SevenZipException {
93         }
94
95         @Override
96         public void setOperationResult(ExtractOperationResult extractOperationResult) throws SevenZipException {
97             if (closeStreamAfterOperation && fos != null) {
98               try {
99                     // 关闭输出流
100                     fos.close();
101               } catch (IOException e) {
102                     throw new SevenZipException("关闭文件输出流时报错", e);
103               } finally {
104                     // 重置标记
105                     closeStreamAfterOperation = false;
106                     // 清除引用,以便垃圾回收
107                     fos = null;
108               }
109             }
110         }
111
112   }
113 }3、编写测试类:创建测试类以验证RAR5文件的解压功能。
1 package rar5;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.util.List;
6
7 public class RAR5ExtractorTest {
8
9   public static void main(String[] args) {
10         File rarDirFile = new File("src/main/resources/rar5Test06.rarbak");
11         File outDirFile = new File("src/main/resources/temp/rar5Test06.rar");
12
13         Rar5DocExtractor extractor = new Rar5DocExtractor();
14         try {
15             List<File> extractedFiles = extractor.extractFiles(rarDirFile, outDirFile);
16             System.out.println("Extracted files:");
17             for (File file : extractedFiles) {
18               System.out.println(file.getAbsolutePath());
19             }
20         } catch (IOException e) {
21             e.printStackTrace();
22         }
23   }
24 } 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Java解压rar5兼容rar4