1 import java.io.File;
2 import java.io.FileNotFoundException;
3 import java.io.FileOutputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.util.Enumeration;
7 import java.util.zip.ZipEntry;
8 import java.util.zip.ZipFile;
9 import de.innosystec.unrar.Archive;
10 import de.innosystec.unrar.exception.RarException;
11 import de.innosystec.unrar.rarfile.FileHeader;
12
13 /**
14 * 對rar或者zip進行解壓縮
15 *
16 * @author yKF41624
17 *
18 */
19 public class Decompress {
20 private static String fileName = "";
21
22 /**
23 * 對rar檔案解壓
24 *
25 * @param rarFileName
26 * @param extPlace
27 * @return
28 */
29 public static boolean unrarFiles(String rarFileName, String extPlace) {
30 boolean flag = false;
31 Archive archive = null;
32 File out = null;
33 File file = null;
34 File dir = null;
35 FileOutputStream os = null;
36 FileHeader fh = null;
37 String path, dirPath = "";
38 try {
39 file = new File(rarFileName);
40 archive = new Archive(file);
41 } catch (RarException e1) {
42 e1.printStackTrace();
43 } catch (IOException e1) {
44 e1.printStackTrace();
45 } finally {
46 if (file != null) {
47 file = null;
48 }
49 }
50 if (archive != null) {
51 try {
52 fh = archive.nextFileHeader();
53 while (fh != null) {
54 fileName = fh.getFileNameString().trim();
55 path = (extPlace + fileName).replaceAll("\\\\", "/");
56 int end = path.lastIndexOf("/");
57 if (end != -1) {
58 dirPath = path.substring(0, end);
59 }
60 try {
61 dir = new File(dirPath);
62 if (!dir.exists()) {
63 dir.mkdirs();
64 }
65 } catch (RuntimeException e1) {
66 e1.printStackTrace();
67 } finally {
68 if (dir != null) {
69 dir = null;
70 }
71 }
72 if (fh.isDirectory()) {
73 fh = archive.nextFileHeader();
74 continue;
75 }
76 out = new File(extPlace + fileName);
77 try {
78 os = new FileOutputStream(out);
79 archive.extractFile(fh, os);
80 } catch (FileNotFoundException e) {
81 e.printStackTrace();
82 } catch (RarException e) {
83 e.printStackTrace();
84 } finally {
85 if (os != null) {
86 try {
87 os.close();
88 } catch (IOException e) {
89 e.printStackTrace();
90 }
91 }
92 if (out != null) {
93 out = null;
94 }
95 }
96 fh = archive.nextFileHeader();
97 }
98 } catch (RuntimeException e) {
99 e.printStackTrace();
100 } finally {
101 fh = null;
102 if (archive != null) {
103 try {
104 archive.close();
105 } catch (IOException e) {
106 e.printStackTrace();
107 }
108 }
109 }
110 flag = true;
111 }
112 return flag;
113 }
114 }
以上代碼解壓無中文的壓縮包是很正常的,經過調試發現,是在的檔案名的時候如果含有中文那麼得到的就是亂碼,即是代碼中的第54行:
Java代碼
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiETPwJWZ3ZCMwcTP39zZuBnLENTJj1mY3VTajhmUzMmZ1IjYqxmMMpnVyoFaxcVY2BjMipWNTpVNWdEZwVTeaZHetllb1cVYxRWbihGbzwkdvR0YwIFSh9CXt92YuM3YltWas5iclN3Ztl2Lc9CX6MHc0RHaiojIsJye.png)
- fileName = fh.getFileNameString().trim();
最開始我查了下API,我發現有一個getFileNameW()方法,就嘗試着用這個方法得到要解壓的檔案名,發現如果有中文一下就成功了,于是 我把上面的方法替換成了這個,可是沒想到如果來的壓縮包沒有英文,那麼就得不到了,于是這就要加個判斷。于是我通過正規表達式判斷檔案名中是否含有中文, 如果有中文,調用getFileNameW(),如果沒有中文就調用getFileNameString()方法,就解決了。
附上判斷字元中是否存在中文的方法:
- public static boolean existZH(String str) {
- String regEx = "[\\u4e00-\\u9fa5]";
- Pattern p = Pattern.compile(regEx);
- Matcher m = p.matcher(str);
- while (m.find()) {
- return true;
- }
- return false;
- }
于是,隻需要将原來的代碼第54行修改為如下代碼即可:
fileName= fh.getFileNameW().trim();
if(!existZH(fileName)){
fileName = fh.getFileNameString().trim();
}
網友評論更好辦法:
主要是55行,由于沒有對extPlace 和 fileName進行路徑分割符進行替換,導緻後面使用fileName的時候,還是會出現檔案名中含有"\"分隔符。是以,在55行前,我添加了一下兩句:
extPlace = extPlace.replaceAll("\\\\", File.separator);
fileName = fileName.replaceAll("\\\\", File.separator);
問題解決。
extPlace = extPlace.replaceAll("\\\\", File.separator);
fileName = fileName.replaceAll("\\\\", File.separator);
File.separator在windows系統與unix系統裡的值分别是什麼? windows是\,unix是/
http://yangjingblog.iteye.com/blog/1134030