Java中解压文件名有中文的rar包出现乱码问题的解决
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行:
- 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行修改为如下代码即可: