java压缩zip文件乱码问题_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > java压缩zip文件乱码问题

java压缩zip文件乱码问题

 2014/7/22 16:00:55  张豆包  程序员俱乐部  我要评论(0)
  • 摘要:对于Java本身,很多功能都会遭到大家的质疑,但是真的是Java本身做的不好么?我想应该不是的。对于Java自身自带的压缩文件操作来说,最大的弊端应该就是对中文的不支持,所以很多人都会去选择apache公司提供的。然而apache公司提供的同样也有语言问题。但Java自身的就不会。在我去网上找过相关的资料,发现除了使用apache的之外,还有去修改源码,而修改源码这种方式,对于很多新手来说,是非常头痛的事情。那就没有解决方式了么?在最近做项目的时候,正好就用到这个压缩文件的操作
  • 标签:文件 Java 问题 压缩 乱码问题

对于Java本身,很多功能都会遭到大家的质疑,但是真的是Java本身做的不好么? 我想应该不是的。

对于Java自身自带的压缩文件操作来说,最大的弊端应该就是对中文的不支持,所以很多人都会去选择apache公司提供的。然而apache公司提供的同样也有语言问题。但Java自身的就不会。

在我去网上找过相关的资料,发现除了使用apache的之外,还有去修改源码,而修改源码这种方式,对于很多新手来说,是非常头痛的事情。那就没有解决方式了么?

在最近做项目的时候,正好就用到这个压缩文件的操作,倒是解决了个别语言乱码的问题。(当然,肯定不是通过修改源码,也不是通过apache)。

因为我用的是jdk1.7的,所以我就用1.7的来说。

?

先说一下,我当时要做的功能:?

?

我的功能能就是用户批量上传一大堆的压缩包,然后我通过后台再开一个线程解析上传的压缩文件,在不解压的情况下,将压缩包中的数据读出来,并将压缩包中需要上传的文件上传到服务器。

?

功能不麻烦,但唯一不能确定的是压缩包中的文件是否是中文命名,如果是中文命名,用java自身自带的zipInputStream就会报错。

通过查看源码,我发现在ZipInputStream中,有两个构造方法:

?

class="java" name="code">public ZipInputStream(InputStream in) {
        this(in, StandardCharsets.UTF_8);
}

public ZipInputStream(InputStream in, Charset charset) {
        super(new PushbackInputStream(in, 512), new Inflater(true), 512);
        usesDefaultInflater = true;
        if(in == null) {
            throw new NullPointerException("in is null");
        }
        if (charset == null)
            throw new NullPointerException("charset is null");
        this.zc = ZipCoder.get(charset);
}

?期初我用的是第一个,也就是只传了一个inputStream进去。但是当报错失败的时候,发现这个构造方法,默认我们的编码为"UTF-8"。那期初我就很费解,我从页面端传递,到数据库所有都统一是"UTF-8"。并且,我的其他上传用"UTF-8"也成功解决了中文问题,那为何这个就不可以呢?

?

在我通过使用第二个构造方法时通过:

 ZipInputStream zip = new ZipInputStream(in,StandardCharsets.UTF-8);

?的方式将UTF-8给传入进去,结果一样的, 当然,这个是意料之中的。(StandardCharsets是Java自身提供的)。

那我的想法是,既然有提供可以自定义编码,那我一个个尝试一下看看?

?

期初,我是想通过设置为"GBK"的方式,

但是,我发现StandardCharsets这个类提供的编码很少:

 public static final Charset US_ASCII = Charset.forName("US-ASCII");

    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");

    public static final Charset UTF_8 = Charset.forName("UTF-8");

    public static final Charset UTF_16BE = Charset.forName("UTF-16BE");

    public static final Charset UTF_16LE = Charset.forName("UTF-16LE");

    public static final Charset UTF_16 = Charset.forName("UTF-16");

?

?

这让我很失望,因为这里面,我能联系到解决中文的方式只有UTF-8。

不过,我很好奇,因为我想不透为何Java只给我们提供考了这几种编码?难道是考虑不周详?

有这个想法后,我就想试试看Java给我们留这几个编码的用意。

"ASCII"码很容易理解,我也感觉也许会把这个流默认读成"ASCII"码呢?

但是,试过之后发现不行,仍然过不了,依然报错。

那就一个一个试一下看看呗。

?

奇迹来了,在我使用"ISO-8859-1"的时候居然通过了。

?

然后,我将通过"ISO-8859-1"转化过来的乱码再次转换,以恢复到以前的汉字状态,这样我就能知道zipInputStream流默认的是什么编码了

在我通过new String的方式来转化的时候,发现只有在转化为"GBK"的时候才能显示原来的汉字状态。

?

那我就大概明白这个问题了。

然后,我就修改自己的代码:

zipFile = new ZipFile(filePath);
			InputStream in = new BufferedInputStream(new FileInputStream(filePath));
			//转化为iso_8859_1,保证zip.getNextEntry()能够通过
	        ZipInputStream zip = new ZipInputStream(in,StandardCharsets.ISO_8859_1);
	        ZipEntry zipEntry;
	        while ((zipEntry = zip.getNextEntry()) != null) {
				//判断是否为目录条目,此处不用操作。
	        	if(zipEntry.isDirectory()){
	        	}else{
	        		//获取文件名(此文件名会包含路径)
	        		String fileName1 = zipEntry.getName();
	        		//此文件名是真正的文件名
	        		String fileName2 = getFileNameByFilePath(fileName1);
	        		System.out.println(fileName2.toString());
                      }
                 }

?将流转为”ISO-8859-1“后,让其顺利通过zip.getNextEntry(),

如果要保存压缩包中文件的真实名字的话,就可以通过

byte[] b = fileName2.getBytes("ISO_8859_1");
new String(b,"GBK");

?来获取原来的名字。

?

  • 相关文章
发表评论
用户名: 匿名