用过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
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();
- }
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)
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();
- }
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);
- }
- }
- }
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);
}
}
}
评论
1 楼
sdyjmc 2011-08-22
引用
最好对传入的输出路径做判断,另外
File f = new File(outputDirectory + File.separator + z.getName());
System.out.println(f.getAbsolutePath());
if(!f.getParentFile().exists()){
f.getParentFile().mkdirs();
}
f.createNewFile();
/*initIDs();*/ 也要注释掉。
static {
/* Zip library is loaded from System.initializeSystemClass */
/*initIDs();*/
}
File f = new File(outputDirectory + File.separator + z.getName());
System.out.println(f.getAbsolutePath());
if(!f.getParentFile().exists()){
f.getParentFile().mkdirs();
}
f.createNewFile();
/*initIDs();*/ 也要注释掉。
static {
/* Zip library is loaded from System.initializeSystemClass */
/*initIDs();*/
}
转载: