Java解压rar5兼容rar4

打印 上一主题 下一主题

主题 846|帖子 846|积分 2538

  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文件中添加相干依赖。
  1. <dependency>
  2.             <groupId>com.github.axet</groupId>
  3.             <artifactId>java-unrar</artifactId>
  4.             <version>1.7.0-8</version>
  5.         </dependency>
  6.         <dependency>
  7.             <groupId>net.sf.sevenzipjbinding</groupId>
  8.             <artifactId>sevenzipjbinding</artifactId>
  9.             <version>16.02-2.01</version>
  10.         </dependency>
  11.         <dependency>
  12.             <groupId>net.sf.sevenzipjbinding</groupId>
  13.             <artifactId>sevenzipjbinding-all-platforms</artifactId>
  14.             <version>16.02-2.01</version>
  15.         </dependency>
复制代码
2、编写解压工具类:创建Rar5DocExtractor类,实现解压逻辑。
  1.   1 package rar5;
  2.   2
  3.   3 import net.sf.sevenzipjbinding.*;
  4.   4 import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
  5.   5
  6.   6 import java.io.*;
  7.   7 import java.util.*;
  8.   8
  9.   9 public class Rar5DocExtractor {
  10. 10
  11. 11     public List<File> extractFiles(File rarFile, File outputDir) throws IOException {
  12. 12         Set<File> extractedFiles = new HashSet<>();
  13. 13         if (!outputDir.exists()) {
  14. 14             outputDir.mkdirs(); // 确保输出目录存在
  15. 15         }
  16. 16
  17. 17         RandomAccessFile randomAccessFile = null;
  18. 18         IInArchive inArchive = null;
  19. 19         try {
  20. 20             randomAccessFile = new RandomAccessFile(rarFile, "r");
  21. 21             inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
  22. 22             int[] in = new int[inArchive.getNumberOfItems()];
  23. 23             for (int i = 0; i < in.length; i++) {
  24. 24                 in[i] = i;
  25. 25             }
  26. 26             inArchive.extract(in, false, new ExtractCallback(inArchive, outputDir.getAbsolutePath(), extractedFiles));
  27. 27         } finally {
  28. 28             if (randomAccessFile != null) {
  29. 29                 randomAccessFile.close();
  30. 30             }
  31. 31             if (inArchive != null) {
  32. 32                 try {
  33. 33                     inArchive.close();
  34. 34                 } catch (SevenZipException e) {
  35. 35                     e.printStackTrace();
  36. 36                 }
  37. 37             }
  38. 38         }
  39. 39         List<File> list=new ArrayList<>(extractedFiles);
  40. 40         return list;
  41. 41     }
  42. 42
  43. 43     private static class ExtractCallback implements IArchiveExtractCallback {
  44. 44         private IInArchive inArchive;
  45. 45         private String outDir;
  46. 46         private Set<File> extractedFiles;
  47. 47         // 用于跟踪是否需要关闭流的变量
  48. 48         private OutputStream fos = null;
  49. 49         private boolean closeStreamAfterOperation = false; // 标记流是否需要关闭
  50. 50
  51. 51         public ExtractCallback(IInArchive inArchive, String outDir, Set<File> extractedFiles) {
  52. 52             this.inArchive = inArchive;
  53. 53             this.outDir = outDir;
  54. 54             this.extractedFiles = extractedFiles;
  55. 55         }
  56. 56
  57. 57         @Override
  58. 58         public void setCompleted(long arg0) throws SevenZipException {
  59. 59         }
  60. 60
  61. 61         @Override
  62. 62         public void setTotal(long arg0) throws SevenZipException {
  63. 63         }
  64. 64
  65. 65
  66. 66         @Override
  67. 67         public ISequentialOutStream getStream(int index, ExtractAskMode extractAskMode) throws SevenZipException {
  68. 68             final String path = (String) inArchive.getProperty(index, PropID.PATH);
  69. 69             // 这里不再创建 File 对象,避免多次调用 getStream 时重复创建
  70. 70             return new ISequentialOutStream() {
  71. 71                 public int write(byte[] data) throws SevenZipException {
  72. 72                     File file = new File(outDir, path);
  73. 73                     try {
  74. 74                         if (data.length == 0) return 0;
  75. 75                         file.getParentFile().mkdirs(); // 确保目录存在
  76. 76                         if (fos == null) { // 如果这是第一次写入,初始化输出流
  77. 77                             fos = new FileOutputStream(file);
  78. 78                             closeStreamAfterOperation = true; // 设置标记,表示需要在操作结果后关闭流
  79. 79                         }
  80. 80                         fos.write(data);
  81. 81                         fos.flush(); // 刷新以确保数据被写入磁盘
  82. 82                         extractedFiles.add(file); // 添加到提取文件集合
  83. 83                     } catch (IOException e) {
  84. 84                         throw new SevenZipException("Error writing data to file: " + path, e);
  85. 85                     }
  86. 86                     return data.length;
  87. 87                 }
  88. 88             };
  89. 89         }
  90. 90
  91. 91         @Override
  92. 92         public void prepareOperation(ExtractAskMode arg0) throws SevenZipException {
  93. 93         }
  94. 94
  95. 95         @Override
  96. 96         public void setOperationResult(ExtractOperationResult extractOperationResult) throws SevenZipException {
  97. 97             if (closeStreamAfterOperation && fos != null) {
  98. 98                 try {
  99. 99                     // 关闭输出流
  100. 100                     fos.close();
  101. 101                 } catch (IOException e) {
  102. 102                     throw new SevenZipException("关闭文件输出流时报错", e);
  103. 103                 } finally {
  104. 104                     // 重置标记
  105. 105                     closeStreamAfterOperation = false;
  106. 106                     // 清除引用,以便垃圾回收
  107. 107                     fos = null;
  108. 108                 }
  109. 109             }
  110. 110         }
  111. 111
  112. 112     }
  113. 113 }
复制代码
3、编写测试类:创建测试类以验证RAR5文件的解压功能。
  1. 1 package rar5;
  2. 2
  3. 3 import java.io.File;
  4. 4 import java.io.IOException;
  5. 5 import java.util.List;
  6. 6
  7. 7 public class RAR5ExtractorTest {
  8. 8
  9. 9     public static void main(String[] args) {
  10. 10         File rarDirFile = new File("src/main/resources/rar5Test06.rarbak");
  11. 11         File outDirFile = new File("src/main/resources/temp/rar5Test06.rar");
  12. 12
  13. 13         Rar5DocExtractor extractor = new Rar5DocExtractor();
  14. 14         try {
  15. 15             List<File> extractedFiles = extractor.extractFiles(rarDirFile, outDirFile);
  16. 16             System.out.println("Extracted files:");
  17. 17             for (File file : extractedFiles) {
  18. 18                 System.out.println(file.getAbsolutePath());
  19. 19             }
  20. 20         } catch (IOException e) {
  21. 21             e.printStackTrace();
  22. 22         }
  23. 23     }
  24. 24 }
复制代码
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

小小小幸运

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表