1. package decompress;
  2.  
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5.  
  6. import org.apache.tools.ant.Project;
  7. import org.apache.tools.ant.taskdefs.Expand;
  8.  
  9. import de.innosystec.unrar.Archive;
  10. import de.innosystec.unrar.rarfile.FileHeader;
  11.  
  12. public class DeCompressUtil {
  13. /**
  14. * 解压zip格式压缩包
  15. * 对应的是ant.jar
  16. */
  17. private static void unzip(String sourceZip,String destDir) throws Exception{
  18. try{
  19. Project p = new Project();
  20. Expand e = new Expand();
  21. e.setProject(p);
  22. e.setSrc(new File(sourceZip));
  23. e.setOverwrite(false);
  24. e.setDest(new File(destDir));
  25. /*
  26. ant下的zip工具默认压缩编码为UTF-8编码,
  27. 而winRAR软件压缩是用的windows默认的GBK或者GB2312编码
  28. 所以解压缩时要制定编码格式
  29. */
  30. e.setEncoding("gbk");
  31. e.execute();
  32. }catch(Exception e){
  33. throw e;
  34. }
  35. }
  36. /**
  37. * 解压rar格式压缩包。
  38. * 对应的是java-unrar-0.3.jar,但是java-unrar-0.3.jar又会用到commons-logging-1.1.1.jar
  39. */
  40. private static void unrar(String sourceRar,String destDir) throws Exception{
  41. Archive a = null;
  42. FileOutputStream fos = null;
  43. try{
  44. a = new Archive(new File(sourceRar));
  45. FileHeader fh = a.nextFileHeader();
  46. while(fh!=null){
  47. if(!fh.isDirectory()){
  48. //1 根据不同的操作系统拿到相应的 destDirName 和 destFileName
  49. String compressFileName = fh.getFileNameString().trim();
  50. String destFileName = "";
  51. String destDirName = "";
  52. //非windows系统
  53. if(File.separator.equals("/")){
  54. destFileName = destDir + compressFileName.replaceAll("\\\\", "/");
  55. destDirName = destFileName.substring(0, destFileName.lastIndexOf("/"));
  56. //windows系统
  57. }else{
  58. destFileName = destDir + compressFileName.replaceAll("/", "\\\\");
  59. destDirName = destFileName.substring(0, destFileName.lastIndexOf("\\"));
  60. }
  61. //2创建文件夹
  62. File dir = new File(destDirName);
  63. if(!dir.exists()||!dir.isDirectory()){
  64. dir.mkdirs();
  65. }
  66. //3解压缩文件
  67. fos = new FileOutputStream(new File(destFileName));
  68. a.extractFile(fh, fos);
  69. fos.close();
  70. fos = null;
  71. }
  72. fh = a.nextFileHeader();
  73. }
  74. a.close();
  75. a = null;
  76. }catch(Exception e){
  77. throw e;
  78. }finally{
  79. if(fos!=null){
  80. try{fos.close();fos=null;}catch(Exception e){e.printStackTrace();}
  81. }
  82. if(a!=null){
  83. try{a.close();a=null;}catch(Exception e){e.printStackTrace();}
  84. }
  85. }
  86. }
  87. /**
  88. * 解压缩
  89. */
  90. public static void deCompress(String sourceFile,String destDir) throws Exception{
  91. //保证文件夹路径最后是"/"或者"\"
  92. char lastChar = destDir.charAt(destDir.length()-1);
  93. if(lastChar!='/'&&lastChar!='\\'){
  94. destDir += File.separator;
  95. }
  96. //根据类型,进行相应的解压缩
  97. String type = sourceFile.substring(sourceFile.lastIndexOf(".")+1);
  98. if(type.equals("zip")){
  99. DeCompressUtil.unzip(sourceFile, destDir);
  100. }else if(type.equals("rar")){
  101. DeCompressUtil.unrar(sourceFile, destDir);
  102. }else{
  103. throw new Exception("只支持zip和rar格式的压缩包!");
  104. }
  105. }
  106. }

RAR压缩算法是不公开的,所以这方面的开源项目不多

幸好有一个叫unrar的开源项目支持RAR的解压,但不能压缩RAR文件

不过,直接使用unrar却不能支持带密码的RAR文件解压,经过多方查找,终于在Google Code上面找到一个支持密码的unrar版本,下载地址:http://code.google.com/p/java-unrar/

该项目依赖Jar包:

commons-logging.jar  比较常用,可以到Apache官网下载

gnu-crypto.jar  可以在http://www.gnu.org/software/gnu-crypto/下载

下面是一个简单的解压示例:

package com.reyo.demo.rar;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.commons.io.IOUtils;

import de.innosystec.unrar.Archive;
import de.innosystec.unrar.exception.RarException;
import de.innosystec.unrar.rarfile.FileHeader;

/**
 * RAR格式压缩文件解压工具类
 * 不支持RAR格式压缩
 * 支持中文,支持RAR压缩文件密码
 * 依赖jar包
 * commons-io.jar
 * commons-logging.jar
 * java-unrar-decryption-supported.jar
 * gnu-crypto.jar
 *
 * @author ninemax
 */
public class RarDecompressionUtil {
 
 public static final String SEPARATOR = File.separator;
 
 // =============================== RAR Format ================================
 /**
  * 解压指定RAR文件到当前文件夹
  * @param srcRar 指定解压
  *  @param password 压缩文件时设定的密码
  * @throws IOException
  */
 public static void unrar(String srcRar, String password) throws IOException {
  unrar(srcRar, null, password);
 }
 
 /**
  * 解压指定的RAR压缩文件到指定的目录中
  * @param srcRar 指定的RAR压缩文件
  * @param destPath 指定解压到的目录
  *  @param password 压缩文件时设定的密码
  * @throws IOException
  */
 public static void unrar(String srcRar, String destPath, String password) throws IOException {
  File srcFile = new File(srcRar);
  if (!srcFile.exists()) {
   return;
  }
  if (null == destPath || destPath.length() == 0) {
   unrar(srcFile, srcFile.getParent(), password);
   return;
  }
  unrar(srcFile,destPath, password);
 }
 
 /**
  * 解压指定RAR文件到当前文件夹
  * @param srcRarFile 解压文件
  *  @param password 压缩文件时设定的密码
  * @throws IOException
  */
 public static void unrar(File srcRarFile, String password) throws IOException {
  if (null == srcRarFile || !srcRarFile.exists()) {
   throw new IOException("指定文件不存在.");
  }
  unrar(srcRarFile, srcRarFile.getParent(),password);
 }
 
 /**
  * 解压指定RAR文件到指定的路径
  * @param srcRarFile 需要解压RAR文件
  * @param destPath 指定解压路径
  * @param password 压缩文件时设定的密码
  * @throws IOException
  */
 public static void unrar(File srcRarFile, String destPath, String password) throws IOException {
  if (null == srcRarFile || !srcRarFile.exists()) {
   throw new IOException("指定压缩文件不存在.");
  }
  if (!destPath.endsWith(SEPARATOR)) {
   destPath += SEPARATOR;
  }
  Archive archive = null;
  OutputStream unOut = null;
  try {
   archive = new Archive(srcRarFile, password, false);
   FileHeader fileHeader = archive.nextFileHeader();
   while(null != fileHeader) {
    if (!fileHeader.isDirectory()) {
     // 1 根据不同的操作系统拿到相应的 destDirName 和 destFileName
     String destFileName = "";
     String destDirName = "";
     if (SEPARATOR.equals("/")) {  // 非windows系统
      destFileName = (destPath + fileHeader.getFileNameW()).replaceAll("\\\\", "/");
      destDirName = destFileName.substring(0, destFileName.lastIndexOf("/"));
     } else {  // windows系统
      destFileName = (destPath + fileHeader.getFileNameW()).replaceAll("/", "\\\\");
      destDirName = destFileName.substring(0, destFileName.lastIndexOf("\\"));
     }
     // 2创建文件夹
     File dir = new File(destDirName);
     if (!dir.exists() || !dir.isDirectory()) {
      dir.mkdirs();
     }
     // 抽取压缩文件
     unOut = new FileOutputStream(new File(destFileName));
     archive.extractFile(fileHeader, unOut);
     unOut.flush();
     unOut.close();
    }
    fileHeader = archive.nextFileHeader();
   }
   archive.close();
  } catch (RarException e) {
   e.printStackTrace();
  } finally {
   IOUtils.closeQuietly(unOut);
  }
 }
}

java解压缩zip和rar的工具类的更多相关文章

  1. Java判断不为空的工具类总结

    1.Java判断是否为空的工具类,可以直接使用.包含,String字符串,数组,集合等等. package com.bie.util; import java.util.Collection; imp ...

  2. Java字符串转16 进制工具类Hex.java

    Java字符串转16 进制工具类Hex.java 学习了:https://blog.csdn.net/jia635/article/details/56678086 package com.strin ...

  3. Java中的AES加解密工具类:AESUtils

    本人手写已测试,大家可以参考使用 package com.mirana.frame.utils.encrypt; import com.mirana.frame.constants.SysConsta ...

  4. java里poi操作excel的工具类(兼容各版本)

    转: java里poi操作excel的工具类(兼容各版本) 下面是文件内具体内容,文件下载: import java.io.FileNotFoundException; import java.io. ...

  5. java.util.Arrays----操作数组的工具类

    java.util.Arrays操作数组的工具类,里面定义了很多操作数组的方法 1.boolean equals(int[] a,int[] b):判断两个数组是否相等. 2.String toStr ...

  6. java将文件打包成ZIP压缩文件的工具类实例

    package com.lanp; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import ja ...

  7. java中自己常用到的工具类-压缩解压zip文件

    package com.ricoh.rapp.ezcx.admintoolweb.util; import java.io.File; import java.io.FileInputStream; ...

  8. java解压缩zip

    依赖的包: <!-- https://mvnrepository.com/artifact/org.apache.ant/ant --> <dependency> <gr ...

  9. Zip包解压工具类

    最近在做项目的自动检测离线升级,使用到了解压zip包的操作,本着拿来主义精神,搞了个工具类(同事那边拿的),用着还不错. package com.winning.polaris.admin.utils ...

随机推荐

  1. 洛谷P3383线性筛素数

    传送门 代码中体现在那个 $ break $ $ prime $ 数组 中的素数是递增的,当 $ i $ 能整除 $ prime[j ] $ ,那么 $ iprime[j+1] $ 这个合数肯定被 $ ...

  2. vs 加载 dll 缓慢

    https://jingyan.baidu.com/article/642c9d34e25cc2644b46f74b.html http://www.it610.com/article/2611781 ...

  3. .NetCore 使用Zipkin 分布式服务追踪监控服务性能

    参考资料 https://zipkin.io/ https://github.com/openzipkin/zipkin/ https://github.com/openzipkin/zipkin4n ...

  4. 当mysql 遇到 ctrl+c

    目的 为了理解MySQL在执行大SQL时,对执行CTRL+C产生的疑惑,本文通过实验测试和源码分析两个方面,对MySQL处理CTRL+C的详细过程进行分析和讲解,从而解除DBA及开发人员对CTRL+C ...

  5. 【算法】后缀自动机(SAM) 初探

    [自动机] 有限状态自动机的功能是识别字符串,自动机A能识别字符串S,就记为$A(S)$=true,否则$A(S)$=false. 自动机由$alpha$(字符集),$state$(状态集合),$in ...

  6. Storm程序的并发机制(重点掌握)

    概念 Workers (JVMs): 在一个物理节点上可以运行一个或多个独立的JVM 进程.一个Topology可以包含一个或多个worker(并行的跑在不同的物理机上), 所以worker proc ...

  7. MapReduce原理1

    Mapreduce是一个分布式运算程序的编程框架,是用户开发“基于hadoop的数据分析应用”的核心框架: Mapreduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算 ...

  8. CSS------li中的宽和高无法修改问题

    如图: 代码:(需要将display属性值设置为inline-block) <ul style="margin-top:50px"> <li style=&quo ...

  9. 解决vue项目打包后背景图片找不到的问题

    在build->webpack.base.conf.js里添加一句代码: 具体位置在module->rules下 publicPath:"../../",

  10. Python3 turtle安装和使用教程

    Python3 turtle安装和使用教程   Turtle库是Python语言中一个很流行的绘制图像的函数库,想象一个小乌龟,在一个横轴为x.纵轴为y的坐标系原点,(0,0)位置开始,它根据一组函数 ...