由於工作需要,寫了一個小工具,利用java來解壓文件然后對文件進行重命名
主要針對三種格式,分別是zip,rar,7z,經過我的多次實踐我發現網上的類庫並不能解壓最新的壓縮格式
對於zip格式:
maven依賴
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-compress</artifactId> <version>1.9</version> </dependency>
代碼如下:
1 private static Boolean unzip(String fileName, String unZipPath, String rename) throws Exception { 2 boolean flag = false; 3 File zipFile = new File(fileName); 4 5 ZipFile zip = null; 6 try { 7 //指定編碼,否則壓縮包里面不能有中文目錄 8 zip = new ZipFile(zipFile, Charset.forName("GBK")); 9 10 for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) { 11 ZipEntry entry = null; 12 try { 13 entry = (ZipEntry) entries.nextElement(); 14 } catch (Exception e) { 15 return flag; 16 } 17 18 String zipEntryName = entry.getName(); 19 InputStream in = zip.getInputStream(entry); 20 String[] split = rename.split("\n"); 21 for (int i = 0; i < split.length; i++) { 22 zipEntryName = zipEntryName.replace(split[i], " ");//這里可以替換原來的名字 23 } 24 String outPath = (unZipPath + zipEntryName).replace("/", File.separator); //解壓重命名 25 26 //判斷路徑是否存在,不存在則創建文件路徑 27 File outfilePath = new File(outPath.substring(0, outPath.lastIndexOf(File.separator))); 28 if (!outfilePath.exists()) { 29 outfilePath.mkdirs(); 30 } 31 //判斷文件全路徑是否為文件夾 32 if (new File(outPath).isDirectory()) { 33 continue; 34 } 35 //保存文件路徑信息 36 //urlList.add(outPath); 37 38 OutputStream out = new FileOutputStream(outPath); 39 byte[] buf1 = new byte[2048]; 40 int len; 41 while ((len = in.read(buf1)) > 0) { 42 out.write(buf1, 0, len); 43 } 44 in.close(); 45 out.close(); 46 } 47 flag = true; 48 //必須關閉,否則無法刪除該zip文件 49 zip.close(); 50 } catch (IOException e) { 51 flag = false; 52 } 53 54 55 return flag; 56 57 }
對於zip的文件大部分可以解壓但是我發現有些的中文編碼得是UTF-8才能解壓,因此設置成GBK 不是絕對的
7z格式的就和網上大部分的代碼類似
maven依賴同上的
1 public static Boolean apache7ZDecomp(String orgPath, String tarpath, String rename) { 2 boolean flag = false; 3 try { 4 SevenZFile sevenZFile = new SevenZFile(new File(orgPath)); 5 SevenZArchiveEntry entry = sevenZFile.getNextEntry(); 6 while (entry != null) { 7 8 // System.out.println(entry.getName()); 9 if (entry.isDirectory()) { 10 11 new File(tarpath + entry.getName()).mkdirs(); 12 entry = sevenZFile.getNextEntry(); 13 continue; 14 } 15 String entryName = entry.getName(); 16 String[] split = rename.split("\n"); 17 for (int i = 0; i < split.length; i++) { 18 entryName = entryName.replace(split[i], "");//這里是對原來的名字進行替換,也可以寫你想要換的名字 19 } 20 String tarpathFileName = (tarpath + entryName).replace("/", File.separator); 21 File fileDir = new File(tarpath); 22 if (!fileDir.exists()) { 23 fileDir.mkdirs(); 24 } 25 FileOutputStream out = new FileOutputStream(tarpathFileName); 26 byte[] content = new byte[(int) entry.getSize()]; 27 sevenZFile.read(content, 0, content.length); 28 out.write(content); 29 out.close(); 30 entry = sevenZFile.getNextEntry(); 31 flag = true; 32 } 33 sevenZFile.close(); 34 } catch (FileNotFoundException e) { 35 return flag; 36 } catch (IOException e) { 37 return flag; 38 } 39 return flag; 40 }
還有一種是用這個類庫:
<dependency> <groupId>net.sf.sevenzipjbinding</groupId> <artifactId>sevenzipjbinding</artifactId> <version>9.20-2.00beta</version> </dependency> <dependency> <groupId>net.sf.sevenzipjbinding</groupId> <artifactId>sevenzipjbinding-all-platforms</artifactId> <version>9.20-2.00beta</version> </dependency>
1 public static void un7ZipFile(String filepath, String targetFilePath, String rename) {
2 3 final File file = new File(targetFilePath); 4 if (!file.exists()) { 5 file.mkdirs(); 6 } 7 RandomAccessFile randomAccessFile = null; 8 IInArchive inArchive = null; 9 10 try { 11 randomAccessFile = new RandomAccessFile(filepath, "r"); 12 inArchive = SevenZip.openInArchive(null, 13 new RandomAccessFileInStream(randomAccessFile)); 14 15 ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface(); 16 17 for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) { 18 final int[] hash = new int[]{0}; 19 if (!item.isFolder()) { 20 ExtractOperationResult result; 21 22 final long[] sizeArray = new long[1]; 23 result = item.extractSlow(new ISequentialOutStream() { 24 public int write(byte[] data) throws SevenZipException { 25 26 FileOutputStream fos = null; 27 try { 28 String fileName = item.getPath(); 29 String[] split = rename.split("\r\n"); 30 for (int i = 0; i < split.length; i++) { 31 fileName = fileName.replace(split[i], ""); 32 } 33 34 File tarFile = new File(file + File.separator + fileName); 35 36 if (!tarFile.getParentFile().exists()) { 37 tarFile.getParentFile().mkdirs(); 38 } 39 tarFile.createNewFile(); 40 fos = new FileOutputStream(tarFile.getAbsolutePath()); 41 fos.write(data); 42 fos.close(); 43 44 } catch (FileNotFoundException e) { 45 46 } catch (IOException e) { 47 48 } 49 50 hash[0] ^= Arrays.hashCode(data); 51 sizeArray[0] += data.length; 52 return data.length; 53 } 54 }); 55 if (result == ExtractOperationResult.OK) { 56 // System.out.println(String.format("%9X | %10s | %s", // 57 // hash[0], sizeArray[0], item.getPath())); 58 } else { 59 // System.err.println("Error extracting item: " + result); 60 } 61 } 62 } 63 } catch (Exception e) { 64 e.printStackTrace(); 65 System.exit(1); 66 } finally { 67 if (inArchive != null) { 68 try { 69 inArchive.close(); 70 } catch (SevenZipException e) { 71 e.printStackTrace(); 72 } 73 } 74 if (randomAccessFile != null) { 75 try { 76 randomAccessFile.close(); 77 } catch (IOException e) { 78 e.printStackTrace(); 79 } 80 } 81 } 82 }
<groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>com.github.junrar</groupId> <artifactId>junrar</artifactId> <version>3.0.0</version> </dependency>
public static boolean unrar(String rarFileName, String outFilePath, String rename) throws Exception { try { Archive archive = new Archive(new File(rarFileName), new UnrarProcessMonitor(rarFileName)); if (archive == null) { throw new FileNotFoundException(rarFileName + " NOT FOUND!"); } if (archive.isEncrypted()) { throw new Exception(rarFileName + " IS ENCRYPTED!"); } List<FileHeader> files = archive.getFileHeaders(); for (FileHeader fh : files) { if (fh.isEncrypted()) { throw new Exception(rarFileName + " IS ENCRYPTED!"); } String fileName = fh.getFileNameW().isEmpty() ? fh.getFileNameString() : fh.getFileNameW(); String[] split = rename.split("\n"); for (int i = 0; i < split.length; i++) { fileName = fileName.replace(split[i], ""); //解壓重命名 } if (fileName != null && fileName.trim().length() > 0) { String saveFileName = outFilePath + File.separator + fileName; File saveFile = new File(saveFileName); File parent = saveFile.getParentFile(); if (!parent.exists()) { parent.mkdirs(); } if (!saveFile.exists()) { saveFile.createNewFile(); } FileOutputStream fos = new FileOutputStream(saveFile); try { archive.extractFile(fh, fos); fos.flush(); fos.close(); } catch (RarException e) { } finally { } } } return true; } catch (Exception e) { System.out.println("failed."); return false; } }
//對解壓rar文件進度的監控
public class UnrarProcessMonitor implements UnrarCallback {
private String fileName;
public UnrarProcessMonitor(String fileName) {
this.fileName = fileName;
}
/**
* 返回false的話,對於某些分包的rar是沒辦法解壓正確的
* */
@Override
public boolean isNextVolumeReady(Volume volume) {
try {
fileName = ((FileVolume) volume).getFile().getCanonicalPath();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
@Override
public void volumeProgressChanged(long l, long l1) {
//輸出進度
System.out.println("Unrar "+fileName+" rate: "+(double)l/l1*100+"%");
}
}
最后就是如果三種方法都無法解壓我們就應該調用cmd來用WinRar進行解壓
public static boolean unfile(String zipFile,String outFilePath,int mode){ boolean flag=false; try{ File file = new File(zipFile); String fileName = file.getName(); if(mode == 1) { outFilePath += File.separator; //文件當前路徑下 }else{ outFilePath += File.separator+fileName.substring(0,fileName.length()-4)+File.separator; } File tmpFileDir = new File(outFilePath); tmpFileDir.mkdirs(); String unrarCmd = "C:\\Program Files\\WinRAR\\WinRar e "; unrarCmd += zipFile + " " + outFilePath; try { Runtime rt = Runtime.getRuntime(); Process p = rt.exec(unrarCmd); InputStream inputStream=p.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); while (br.readLine()!=null){ } p.waitFor(); br.close(); inputStream.close(); p.getErrorStream().close(); p.getOutputStream().close(); flag=true; } catch (Exception e) { System.out.println(e.getMessage()); } }catch(Exception e){ } return flag; }
以上就是解壓的方法,總體坐下來感覺還是調用cmd最簡單直接,然后壓縮的話基本上大部分都可以壓縮,就不寫上壓縮的代碼了