中文亂碼 解壓

用過java做壓縮或解壓的都知道,jdk提供的zip只能按UTF-8格式處理,前些天寫過一篇壓縮zip的中文問題,就是使用ant包裏的類,並且在linux上稍做些修改也能兼容,但是,如果是解壓一個包含中文文件名的zip包呢? 此時如果使用jdk自帶的zip包,解壓時如果文件名有中文,會抱非法參數異常,而如果使用ant包。會發現ant.jar裏並沒有ZipInputStream,怎麼辦?
    看來,我們還是得使用jdk裏的zip包了,我們的問題僅僅是需要支持GBK,所以修改應該不會很大,所以我們先找出所有相關的類,以下類請自行從jdk的src.zip裏提取

Java代碼 複製代碼 收藏代碼
  1. DeflaterOutputStream.java   
  2. InflaterInputStream.java   
  3. ZipConstants.java   
  4. ZipEntry.java   
  5. ZipInputStream.java   
  6. ZipOutputStream.java  
DeflaterOutputStream.java
InflaterInputStream.java
ZipConstants.java
ZipEntry.java
ZipInputStream.java
ZipOutputStream.java


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

    前面不是說ant.jar裏並沒有ZipInputStream.java嘛,這裏需要修改的正是這個類,找到getUTF8String()方法,。(這裏要汗一個,。sun是怎麼想的,連方法名都規定死了是UTF-8),在這個方法裏的所有代碼前加上如下:

Java代碼 複製代碼 收藏代碼
  1. try  
  2.        {   
  3.            String s = new String(b, off, len, "GBK");//以GBK的方式  
  4.            return s;   
  5.        }   
  6.        catch (UnsupportedEncodingException e)   
  7.        {   
  8.            e.printStackTrace();   
  9.        }  
 try
        {
            String s = new String(b, off, len, "GBK");//以GBK的方式
            return s;
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }



此時就完成以GBK方式操作,但是此時我們在解壓時,還會發現問題,報如下異常:
Java代碼 複製代碼 收藏代碼
  1. Exception in thread "main" java.lang.UnsatisfiedLinkError: com.zwl.zip.ZipEntry.initIDs()V   
  2.     at com.zwl.zip.ZipEntry.initIDs(Native Method)   
  3.     at com.zwl.zip.ZipEntry.<clinit>(ZipEntry.java:41)   
  4.     at com.zwl.zip.ZipInputStream.createZipEntry(ZipInputStream.java:389)   
  5.     at com.zwl.zip.ZipInputStream.readLOC(ZipInputStream.java:251)   
  6.     at com.zwl.zip.ZipInputStream.getNextEntry(ZipInputStream.java:78)   
  7.     at com.conngame.test.TestZip.unzip(TestZip.java:41)   
  8.     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模塊,註釋掉就行了,

Java代碼 複製代碼 收藏代碼
  1. static  
  2.    {   
  3.        /* Zip library is loaded from System.initializeSystemClass */  
  4.        initIDs();   
  5.    }  
 static
    {
        /* Zip library is loaded from System.initializeSystemClass */
        initIDs();
    }


    找到以上代碼註釋掉.此時解壓,OK,能完美支持中文

   附上測試代碼:

Java代碼 複製代碼 收藏代碼
  1. package com.conngame.test;   
  2.   
  3. import java.io.File;   
  4. import java.io.FileInputStream;   
  5. import java.io.FileOutputStream;   
  6.   
  7. import com.zwl.zip.ZipEntry;   
  8. import com.zwl.zip.ZipInputStream;   
  9. import com.zwl.zip.ZipOutputStream;   
  10.   
  11. /**  
  12.  * TestZip.java coding by Serol Luo. [email protected] 2003/07/03 
  13.  * http://www.chinaunix.net/forum/viewforum.php?f=26 轉載請保留此信息 
  14.  */  
  15.   
  16. class TestZip   
  17. {   
  18.     public void zip(String zipFileName, String inputFile) throws Exception   
  19.     {   
  20.         zip(zipFileName, new File(inputFile));   
  21.     }   
  22.     public void zip(String zipFileName, File inputFile) throws Exception   
  23.     {   
  24.         ZipOutputStream out = new ZipOutputStream(new FileOutputStream(   
  25.                 zipFileName));   
  26.         zip(out, inputFile, "");   
  27.         System.out.println("zip done");   
  28.         out.close();   
  29.     }   
  30.   
  31.     public void unzip(String zipFileName, String outputDirectory)   
  32.             throws Exception   
  33.     {   
  34.         ZipInputStream in = new ZipInputStream(new FileInputStream(zipFileName));   
  35.         ZipEntry z;   
  36.            
  37. //        System.out.println("z = in.getNextEntry(): "+((z=in.getNextEntry())!=null));  
  38.            
  39.            
  40.            
  41.         while ((z=in.getNextEntry())!=null)   
  42.         {   
  43.             System.out.println("unziping " + z.getName());   
  44.             if (z.isDirectory())   
  45.             {   
  46.                 String name = z.getName();   
  47.                 name = name.substring(0, name.length() - 1);   
  48.                 File f = new File(outputDirectory + File.separator + name);   
  49.                 f.mkdir();   
  50.                 System.out.println("mkdir " + outputDirectory + File.separator   
  51.                         + name);   
  52.             }   
  53.             else  
  54.             {   
  55.                 File f = new File(outputDirectory + File.separator   
  56.                         + z.getName());   
  57.                 f.createNewFile();   
  58.                 System.out.println("f:" +f);   
  59.                 FileOutputStream out = new FileOutputStream(f);   
  60.                 int b;   
  61.                 while ((b = in.read()) != -1)   
  62.                     out.write(b);   
  63.                 out.close();   
  64.             }   
  65.         }   
  66.   
  67.         in.close();   
  68.     }   
  69.   
  70.     public void zip(ZipOutputStream out, File f, String base) throws Exception   
  71.     {   
  72.         System.out.println("Zipping  " + f.getName());   
  73.         if (f.isDirectory())   
  74.         {   
  75.             File[] fl = f.listFiles();   
  76.             out.putNextEntry(new ZipEntry(base + "/"));   
  77.             base = base.length() == 0 ? "" : base + "/";   
  78.             for (int i = 0; i < fl.length; i++)   
  79.             {   
  80.                 zip(out, fl[i], base + fl[i].getName());   
  81.             }   
  82.         }   
  83.         else  
  84.         {   
  85.             out.putNextEntry(new ZipEntry(base));   
  86.             FileInputStream in = new FileInputStream(f);   
  87.             int b;   
  88.             while ((b = in.read()) != -1)   
  89.                 out.write(b);   
  90.             in.close();   
  91.         }   
  92.   
  93.     }   
  94.     public static void main(String[] args)   
  95.     {   
  96.         try  
  97.         {   
  98.             TestZip t = new TestZip();   
  99.             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\\");   
  100.         }   
  101.         catch (Exception e)   
  102.         {   
  103.             e.printStackTrace(System.out);   
  104.         }   
  105.     }   
  106. }  
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);
        }
    }
}

 

 

 

 

 

 

評論

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();*/
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

轉載:

http://zwllxs.iteye.com/blog/871260

發佈了5 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章