Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 363|回复: 0

Java中解压文件名有中文的rar包出现乱码问题的解决

[复制链接]
  • TA的每日心情
    奋斗
    昨天 22:25
  • 签到天数: 790 天

    [LV.10]以坛为家III

    2049

    主题

    2107

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    722766
    发表于 2021-5-28 21:32:23 | 显示全部楼层 |阅读模式
      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代码   收藏代码
    1. fileName = fh.getFileNameString().trim();  

     

    最开始我查了下API,我发现有一个getFileNameW()方法,就尝试着用这个方法得到要解压的文件名,发现如果有中文一下就成功了,于是 我把上面的方法替换成了这个,可是没想到如果来的压缩包没有英文,那么就得不到了,于是这就要加个判断。于是我通过正则表达式判断文件名中是否含有中文, 如果有中文,调用getFileNameW(),如果没有中文就调用getFileNameString()方法,就解决了。

    附上判断字符中是否存在中文的方法:

    1. public static boolean existZH(String str) {  
    2.     String regEx = "[\\u4e00-\\u9fa5]";  
    3.     Pattern p = Pattern.compile(regEx);  
    4.     Matcher m = p.matcher(str);  
    5.     while (m.find()) {  
    6.         return true;  
    7.     }  
    8.     return false;  
    9. }  

     

    于是,只需要将原来的代码第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
    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-9-11 17:50 , Processed in 1.097873 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表