java实现对常用.ZIP , .TAR, .TAR.BZ2, .BZ2 ,.TAR.GZ ,.GZ格式文件的解压。
首先需要引入maven依赖,这里使用的是Apache的压缩工具包common-compress,改工具包支持解压、压缩,此代码中我列举出一个zip的压缩示例,其他格式的只需切换改格式对应的流即可。
对于RAR格式文件的解压,目前该工具包还不支持,希望大家做过的可以多多交流。
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.19</version>
</dependency>
1 import org.apache.commons.compress.archivers.tar.TarArchiveEntry; 2 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; 3 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; 4 import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; 5 import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; 6 import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; 7 import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; 8 import org.apache.commons.compress.utils.IOUtils; 9 import java.io.*; 10
11 /**
12 * @author :zhangzhiyong 13 * @description: java实现常见文件格式的解压与压缩 14 * 支持.ZIP .TAR .TAR.BZ2 .BZ2 .TAR.GZ .GZ 15 * 其他格式compress包也支持,在此基础上开发即可 16 * 另外压缩文件只写了ZIP压缩的方法zipCompression,其他的格式类似,换成对应的文件流即可。 17 * 暂不支持RAR压缩格式,RAR可以用junrar的工具包,但是有缺陷: 18 * 其一:如果压缩文件中有中文名字的文件夹,解压以后文件夹名字是乱码,但是不影响文件夹里面的文件; 19 * 其二:最新 WinRar 压缩产生的 .rar 文件可能会无法解压。 20 * 缺陷原因:rar 有版权,有些东西没有公开,对解压有一些限制,即使其他解压包也可能有问题,但是建议尝试。 21 * @date :2020/7/1 20:44 22 */
23 public class CompressionFileUtil { 24 /**
25 * @param filePath 需要解压的zip文件的完成路径。 26 * @param unzipPath 解压过后生成文件的存放路径 27 * @description: 对zip文件进行解压。 28 * @return: boolean 29 * @author: ZZY 30 * @time: 2020/7/2 14:47 31 */
32 public static boolean zipUnCompress(String filePath, String unzipPath) throws IOException { 33
34 System.out.println("开始解压ZIP.........."); 35 FileInputStream fis = null; 36 ZipArchiveInputStream zis = null; 37 try { 38 File file = new File(filePath); 39 fis = new FileInputStream(file); 40 zis = new ZipArchiveInputStream(fis); 41 ZipArchiveEntry nze = null; 42 while ((nze = zis.getNextZipEntry()) != null) { 43 FileOutputStream os = null; 44 BufferedOutputStream bos = null; 45 try { 46 System.out.println("正在解压....." + nze.getName()); 47 //自动添加File.separator文件路径的分隔符,根据系统判断是\\还是/
48 String dir = unzipPath + File.separator + nze.getName(); //解压全路径
49 System.out.println("dir---" + dir); 50 File file1 = null; 51 if (nze.isDirectory()) { 52 file1 = new File(dir); 53 file1.mkdirs(); 54 } else { 55 file1 = new File(dir); 56 os = new FileOutputStream(file1); 57 bos = new BufferedOutputStream(os); 58 /*byte [] bt = new byte[1024]; 59 int len = 0; 60 while((len = zis.read(bt,0,1024)) != -1){ 61 bos.write(bt,0,len); 62 }*/
63 IOUtils.copy(zis, bos); //作用与上面注释代码一样
64 } 65 System.out.println("解压完成......"); 66 } catch (FileNotFoundException e) { 67 e.printStackTrace(); 68 return false; 69 } finally { 70 if (bos != null) { 71 bos.close(); 72 } 73 if (os != null) { 74 os.close(); 75 } 76 } 77 } 78 } catch (Exception e) { 79 e.printStackTrace(); 80 return false; 81 } finally { 82 if (zis != null) { 83 zis.close(); 84 } 85 if (fis != null) { 86 fis.close(); 87 } 88 } 89 return true; 90 } 91
92 /**
93 * @param filesPathArray 多个文件的绝对路径,是一个数组。 94 * @param zipFilePath 生成的压缩文件的位置,包括生成的文件名,如D:\zip\test.zip 95 * @description: 将多个文件压缩成ZIP压缩包。 96 * @return: boolean 97 * @author: ZZY 98 * @time: 2020/7/2 14:42 99 */
100 public static boolean zipCompression(String[] filesPathArray, String zipFilePath) throws Exception { 101 System.out.println("开始压缩ZIP文件"); 102 ZipArchiveOutputStream zos = null; 103 FileOutputStream fos = null; 104 try { 105 fos = new FileOutputStream(new File(zipFilePath)); 106 zos = new ZipArchiveOutputStream(fos); 107 for (String filePath : filesPathArray) { 108 FileInputStream fis = null; 109 BufferedInputStream bis = null; 110 try { 111 File file = new File(filePath); 112 // 第二个参数如果是文件全路径名,那么压缩时也会将路径文件夹也缩进去; 113 // 我们只压缩目标文件,而不压缩该文件所处位置的相关文件夹,所以这里我们用file.getName()
114 System.out.println("开始压缩..." + file.getName()); 115 ZipArchiveEntry zae = new ZipArchiveEntry(file, file.getName()); 116 zos.putArchiveEntry(zae); 117 fis = new FileInputStream(file); 118 bis = new BufferedInputStream(fis); 119 int count; 120 byte[] bt = new byte[1024]; 121 while ((count = bis.read(bt, 0, 1024)) != -1) { 122 zos.write(bt, 0, count); 123 } 124 } finally { 125 zos.closeArchiveEntry(); 126 if (bis != null) 127 bis.close(); 128 if (fis != null) 129 fis.close(); 130 } 131 } 132 } finally { 133 if (zos != null) 134 zos.close(); 135 if (fos != null) 136 fos.close(); 137 } 138 System.out.println("压缩完成......"); 139 return true; 140 } 141
142 /**
143 * @param inputStream 每种TAR文件用不同的输入流,unCompress方法中已注明 144 * @param unTarPath TAR文件解压后的存放路径 145 * @description: 解压TAR类文件,包括.TAR .TAR.BZ2 .TAR.GZ 146 * @return: void 147 * @author: ZZY 148 * @time: 2020/7/2 17:42 149 */
150 public static void unTar(InputStream inputStream, String unTarPath) throws IOException { 151
152 FileInputStream fis = null; 153 TarArchiveInputStream tis = null; 154 try { 155 tis = new TarArchiveInputStream(inputStream); 156 TarArchiveEntry nte = null; 157 System.out.println("开始解压......"); 158 while ((nte = tis.getNextTarEntry()) != null) { 159 String dir = unTarPath + File.separator + nte.getName(); 160 System.out.println("正在解压......" + dir); 161 FileOutputStream fos = null; 162 BufferedOutputStream bos = null; 163 try { 164 if (nte.isDirectory()) { 165 File file1 = new File(dir); 166 file1.mkdirs(); 167 } else { 168 File file2 = new File(dir); 169 fos = new FileOutputStream(file2); 170 bos = new BufferedOutputStream(fos); 171 IOUtils.copy(tis, bos); 172 } 173 } catch (Exception e) { 174 e.printStackTrace(); 175 } finally { 176 if (bos != null) { 177 bos.close(); 178 } 179 if (fos != null) { 180 fos.close(); 181 } 182 } 183 } 184 System.out.println("解压完成......"); 185 } catch (IOException e) { 186 e.printStackTrace(); 187 } finally { 188 if (tis != null) { 189 tis.close(); 190 } 191 if (fis != null) { 192 fis.close(); 193 } 194 } 195 } 196
197 public static boolean unCompress(String filePath,String unCompressPath) throws Exception { 198 String fileType = filePath.toUpperCase(); 199 if(fileType.endsWith(".TAR")){ 200 System.out.println("解压的.TAR包"); 201 //.TAR包用一般的FileInputStream流读取
202 unTar(new FileInputStream(filePath),unCompressPath); 203 } 204 else if(fileType.endsWith(".TAR.GZ")){ 205 System.out.println("解压的.TAR.GZ包"); 206 //.TAR.GZ包要用GzipCompressorInputStream读取
207 unTar(new GzipCompressorInputStream(new FileInputStream(filePath)),unCompressPath); 208 } 209 else if(fileType.endsWith(".TAR.BZ2")){ 210 System.out.println("解压的.TAR.BZ2包"); 211 unTar(new BZip2CompressorInputStream(new FileInputStream(filePath)),unCompressPath); 212 } 213 else if(fileType.endsWith(".ZIP")){ 214 System.out.println("解压的.ZIP包"); 215 zipUnCompress(filePath,unCompressPath); 216 } 217 else{ 218 System.out.println("暂不支持该种格式文件的解压"); 219 } 220 return true; 221 } 222
223 public static void main(String[] args) throws Exception { 224
225 unCompress("D:\\test\\zip\\nginx-1.18.0.rar","D:\\test\\zip"); 226
227 } 228
229 }