java 解压zip 中文问题完美解决

用过java做压缩或解压的都知道,jdk提供的zip只能按UTF-8格式处理,前些天写过一篇压缩zip的中文问题,就是使用ant包里的类,并且在linux上稍做些修改也能兼容,但是,如果是解压一个包含中文文件名的zip包呢? 此时如果使用jdk自带的zip包,解压时如果文件名有中文,会抱非法参数异常,而如果使用ant包。会发现ant.jar里并没有ZipInputStream,怎么办?
看来,我们还是得使用jdk里的zip包了,我们的问题仅仅是需要支持GBK,所以修改应该不会很大,所以我们先找出所有相关的类,以下类请自行从jdk的src.zip里提取

DeflaterOutputStream.java
InflaterInputStream.java
ZipConstants.java
ZipEntry.java
ZipInputStream.java
ZipOutputStream.java


以上java文件我已打包在附件中.

前面不是说ant.jar里并没有ZipInputStream.java嘛,这里需要修改的正是这个类,找到getUTF8String()方法,。(这里要汗一个,。sun是怎么想的,连方法名都规定死了是UTF-8),在这个方法里的所有代码前加上如下:

 try
{
String s = new String(b, off, len, "GBK");//以GBK的方式
return s;
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}



此时就完成以GBK方式操作,但是此时我们在解压时,还会发现问题,报如下异常:
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.zwl.zip.ZipEntry.initIDs()V
at com.zwl.zip.ZipEntry.initIDs(Native Method)
at com.zwl.zip.ZipEntry.<clinit>(ZipEntry.java:41)
at com.zwl.zip.ZipInputStream.createZipEntry(ZipInputStream.java:389)
at com.zwl.zip.ZipInputStream.readLOC(ZipInputStream.java:251)
at com.zwl.zip.ZipInputStream.getNextEntry(ZipInputStream.java:78)
at com.conngame.test.TestZip.unzip(TestZip.java:41)
at com.conngame.test.TestZip.main(TestZip.java:100)



initIDs()方法是在ZipEntry类的static里调用的,目前还不大清楚这个到底做什么用,我们只需要在ZipEntry类中找到这个static模块,注释掉就行了,

 static
{
/* Zip library is loaded from System.initializeSystemClass */
initIDs();
}


找到以上代码注释掉.此时解压,OK,能完美支持中文

附上测试代码:

package com.conngame.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import com.zwl.zip.ZipEntry;
import com.zwl.zip.ZipInputStream;
import com.zwl.zip.ZipOutputStream;

/**
* TestZip.java coding by Serol Luo. rollingpig@163.com 2003/07/03
* http://www.chinaunix.net/forum/viewforum.php?f=26 转载请保留此信息
*/

class TestZip
{
public void zip(String zipFileName, String inputFile) throws Exception
{
zip(zipFileName, new File(inputFile));
}
public void zip(String zipFileName, File inputFile) throws Exception
{
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
zipFileName));
zip(out, inputFile, "");
System.out.println("zip done");
out.close();
}

public void unzip(String zipFileName, String outputDirectory)
throws Exception
{
ZipInputStream in = new ZipInputStream(new FileInputStream(zipFileName));
ZipEntry z;

// System.out.println("z = in.getNextEntry(): "+((z=in.getNextEntry())!=null));



while ((z=in.getNextEntry())!=null)
{
System.out.println("unziping " + z.getName());
if (z.isDirectory())
{
String name = z.getName();
name = name.substring(0, name.length() - 1);
File f = new File(outputDirectory + File.separator + name);
f.mkdir();
System.out.println("mkdir " + outputDirectory + File.separator
+ name);
}
else
{
File f = new File(outputDirectory + File.separator
+ z.getName());
f.createNewFile();
System.out.println("f:" +f);
FileOutputStream out = new FileOutputStream(f);
int b;
while ((b = in.read()) != -1)
out.write(b);
out.close();
}
}

in.close();
}

public void zip(ZipOutputStream out, File f, String base) throws Exception
{
System.out.println("Zipping " + f.getName());
if (f.isDirectory())
{
File[] fl = f.listFiles();
out.putNextEntry(new ZipEntry(base + "/"));
base = base.length() == 0 ? "" : base + "/";
for (int i = 0; i < fl.length; i++)
{
zip(out, fl[i], base + fl[i].getName());
}
}
else
{
out.putNextEntry(new ZipEntry(base));
FileInputStream in = new FileInputStream(f);
int b;
while ((b = in.read()) != -1)
out.write(b);
in.close();
}

}
public static void main(String[] args)
{
try
{
TestZip t = new TestZip();
t.unzip("D:\\program\\servers\\apache-tomcat-6.0.9\\apache-tomcat-6.0.9\\webapps\\Manage\\xxx.zip", "D:\\program\\servers\\apache-tomcat-6.0.9\\apache-tomcat-6.0.9\\webapps\\Manage\\");
}
catch (Exception e)
{
e.printStackTrace(System.out);
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值