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 }