用过java做压缩或解压的都知道,jdk提供的zip只能按UTF-8格式处理,前些天写过一篇压缩zip的中文问题,就是使用ant包里的类,并且在linux上稍做些修改也能兼容,但是,如果是解压一个包含中文文件名的zip包呢? 此时如果使用jdk自带的zip包,解压时如果文件名有中文,会抱非法参数异常,而如果使用ant包。会发现ant.jar里并没有ZipInputStream,怎么办?
看来,我们还是得使用jdk里的zip包了,我们的问题仅仅是需要支持GBK,所以修改应该不会很大,所以我们先找出所有相关的类,以下类请自行从jdk的src.zip里提取
以上java文件我已打包在附件中.
前面不是说ant.jar里并没有ZipInputStream.java嘛,这里需要修改的正是这个类,找到getUTF8String()方法,。(这里要汗一个,。sun是怎么想的,连方法名都规定死了是UTF-8),在这个方法里的所有代码前加上如下:
此时就完成以GBK方式操作,但是此时我们在解压时,还会发现问题,报如下异常:
initIDs()方法是在ZipEntry类的static里调用的,目前还不大清楚这个到底做什么用,我们只需要在ZipEntry类中找到这个static模块,注释掉就行了,
找到以上代码注释掉.此时解压,OK,能完美支持中文
附上测试代码:
看来,我们还是得使用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);
}
}
}