`

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

    博客分类:
  • Java
 
阅读更多

之前一直在用java-unrar-0.3.jar来解压rar文件包,一直很正常,但是今天来了个中文名字的包,类似于这样的结构:

压缩包.rar,这个压缩包里面还有个文件夹也叫压缩包,在解压这个压缩包的时候出现了乱码,研究了好久,已经解决,现与大家分享下。

 

原来解压文件的代码:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import de.innosystec.unrar.Archive;
import de.innosystec.unrar.exception.RarException;
import de.innosystec.unrar.rarfile.FileHeader;

/**
 * 对rar或者zip进行解压缩
 * 
 * @author yKF41624
 * 
 */
public class Decompress {
	private static String fileName = "";

	/**
	 * 对rar文件解压
	 * 
	 * @param rarFileName
	 * @param extPlace
	 * @return
	 */
	public static boolean unrarFiles(String rarFileName, String extPlace) {
		boolean flag = false;
		Archive archive = null;
		File out = null;
		File file = null;
		File dir = null;
		FileOutputStream os = null;
		FileHeader fh = null;
		String path, dirPath = "";
		try {
			file = new File(rarFileName);
			archive = new Archive(file);
		} catch (RarException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		} finally {
			if (file != null) {
				file = null;
			}
		}
		if (archive != null) {
			try {
				fh = archive.nextFileHeader();
				while (fh != null) {
					fileName = fh.getFileNameString().trim();
					path = (extPlace + fileName).replaceAll("\\\\", "/");
					int end = path.lastIndexOf("/");
					if (end != -1) {
						dirPath = path.substring(0, end);
					}
					try {
						dir = new File(dirPath);
						if (!dir.exists()) {
							dir.mkdirs();
						}
					} catch (RuntimeException e1) {
						e1.printStackTrace();
					} finally {
						if (dir != null) {
							dir = null;
						}
					}
					if (fh.isDirectory()) {
						fh = archive.nextFileHeader();
						continue;
					}
					out = new File(extPlace + fileName);
					try {
						os = new FileOutputStream(out);
						archive.extractFile(fh, os);
					} catch (FileNotFoundException e) {
						e.printStackTrace();
					} catch (RarException e) {
						e.printStackTrace();
					} finally {
						if (os != null) {
							try {
								os.close();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
						if (out != null) {
							out = null;
						}
					}
					fh = archive.nextFileHeader();
				}
			} catch (RuntimeException e) {
				e.printStackTrace();
			} finally {
				fh = null;
				if (archive != null) {
					try {
						archive.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
			flag = true;
		}
		return flag;
	}
}

 

 

 以上代码解压无中文的压缩包是很正常的,经过调试发现,是在的文件名的时候如果含有中文那么得到的就是乱码,即是代码中的第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行修改为如下代码即可:

fileName=  fh.getFileNameW().trim();
				if(!existZH(fileName)){
					fileName = fh.getFileNameString().trim();
				}

 最后在附上所用jar包。

分享到:
评论
10 楼 lannerK 2013-07-03  
楼主,不用写这种方法判断啊,
FileHeader 有个方法是判断文件名是不是Unicode字符,如果是的话要用
getFileNameW
你这个只能解决中文的乱码,不能解决其他 Unicode文件名的乱码,所以正确应该
这样写

String entrypath = "";
if(fh.isUnicode()){
  entrypath = fh.getFileNameW().trim();
}else{
  entrypath = fh.getFileNameString().trim();  
}
9 楼 大象06 2013-05-16  
Kevin_fan 写道
太感谢了,帮我解决乱码问题。 关键在于楼主查API。 你是怎么查的呢?

这能怎么查嘛,就是用代码提示去看有没有类似的方法的。
8 楼 Kevin_fan 2013-05-15  
太感谢了,帮我解决乱码问题。 关键在于楼主查API。 你是怎么查的呢?
7 楼 大象06 2013-04-03  
songjiesdnu 写道
非常感谢楼主,解决了我的一个大问题。
另外,楼主的这段代码还有点小的问题,我也是在尝试解决自己问题的过程中发现的。
主要是55行,由于没有对extPlace 和 fileName进行路径分割符进行替换,导致后面使用fileName的时候,还是会出现文件名中含有"\"分隔符。所以,在55行前,我添加了一下两句:
extPlace = extPlace.replaceAll("\\\\", File.separator);
fileName = fileName.replaceAll("\\\\", File.separator);
问题解决。

另外,对于"\"的替换,使用replaceAll("\\\\", File.separator)是不是更好呢?

再次感谢楼主!!

是的,感谢你的提示,很有道理!
6 楼 songjiesdnu 2013-04-02  
非常感谢楼主,解决了我的一个大问题。
另外,楼主的这段代码还有点小的问题,我也是在尝试解决自己问题的过程中发现的。
主要是55行,由于没有对extPlace 和 fileName进行路径分割符进行替换,导致后面使用fileName的时候,还是会出现文件名中含有"\"分隔符。所以,在55行前,我添加了一下两句:
extPlace = extPlace.replaceAll("\\\\", File.separator);
fileName = fileName.replaceAll("\\\\", File.separator);
问题解决。

另外,对于"\"的替换,使用replaceAll("\\\\", File.separator)是不是更好呢?

再次感谢楼主!!
5 楼 qbl_experience 2013-02-01  
不错,非常好
4 楼 huzhenkui 2012-08-07  
谢谢分享,这个问题困扰我了两天了,终于解决了rar在linux上解压的乱码问题!
3 楼 chero 2012-06-11  
  非常不错!非常详细。
2 楼 NBUsher 2012-03-31  
找的就是它!!谢谢
1 楼 jian1120java 2012-02-21  
非常不错!非常详细。

相关推荐

Global site tag (gtag.js) - Google Analytics