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.(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. [email protected] 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);
        }
    }
}




 
  • zip.rar (15.1 KB)
  • 下载次数: 530

你可能感兴趣的:(Java,Tomcat,Ant,F#,JDK)