解決ZipInputStream不能正確處理中文檔案名稱

來源:互聯網
上載者:User
我們知道,java對於文字的編碼是以unicode為基礎,因此,若是以ZipInputStream及ZipOutputStream來處理壓縮及解壓縮的工作,碰到中文檔名或路徑,那當然是以unicode來處理羅!
但是,現在市面上的壓縮及解壓縮軟體,例如winzip,卻是不支援unicode的,一碰到檔名以unicode編碼的檔案,它就不處理。
那要如何才能做出讓winzip能夠處理的壓縮檔呢?那就得從修改ZipInputStream及ZipOutputStream對於檔名的編碼方式來著手了。我們可以從jdk的src.zip取得ZipInputStream及ZipOutputStream的原始碼來加以修改:

一、ZipOutputStream.java
1.從jdk的src.zip取得ZipOutputStream.java原始碼,另存新檔存到c:/java/util/zip這個資料夾裡,檔名改為CZipOutputStream.java。
2.開始修改原始碼,將class名稱改為CZipOutputStream
3.建構式也必須更改為CZipOutputStream
4.新增member,這個member記錄編碼方式
  private String encoding="UTF-8";
5.再新增一個建構式(這個建構式可以讓這個class在new的時候,設定檔名的編碼)
  public CZipOutputStream(OutputStream out,String encoding) {
     super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true));
     usesDefaultDeflater = true;
     this.encoding=encoding;
  }
6.找到byte[] nameBytes = getUTF8Bytes(e.name);(有二個地方),將它修改如下:
  byte[] nameBytes = null;
  try
  {
    if (this.encoding.toUpperCase().equals("UTF-8"))
       nameBytes =getUTF8Bytes(e.name);
    else
       nameBytes= e.name.getBytes(this.encoding);
  }
  catch(Exception byteE)
  {
    nameBytes=getUTF8Bytes(e.name);
  }
7.將檔案儲存在c:/java/util/zip這個資料夾內,請記得一定要有這個路徑結構,
才能把CZipOutputStream.class放在正確的package結構裡

二、ZipInputStream.java
1.從jdk的src.zip取得ZipInputStream.java原始碼,另存新檔存到c:/java/util/zip這個資料夾裡,檔名改為CZipInputStream.java。
2.開始修改原始碼,將class名稱改為CZipInputStream
3.建構式也必須更改為CZipInputStream
4.新增member,這個member記錄編碼方式
  private String encoding="UTF-8";
5.再新增一個建構式如下(這個建構式可以讓這個class在new的時候,設定檔名的編碼)
public CZipInputStream(InputStream in,String encoding) {
  super(new PushbackInputStream(in,512),new Inflater(true),512);
  usesDefaultInflater = true;
  if(in == null) {
       throw new NullPointerException("in is null");
  }
  this.encoding=encoding;
}

6.找到ZipEntry e = createZipEntry(getUTF8String(b, 0, len));這一行,將它改成如下:
ZipEntry e=null;
try
{
  if (this.encoding.toUpperCase().equals("UTF-8"))
     e=createZipEntry(getUTF8String(b, 0, len));
  else
     e=createZipEntry(new String(b,0,len,this.encoding));
}
catch(Exception byteE)
{
  e=createZipEntry(getUTF8String(b, 0, len));
}
7.將檔案儲存在c:/java/util/zip這個資料夾內,請記得一定要有這個路徑結構,才能把CZipInputStream.class放在正確的package結構裡

以上兩個檔案儲存後compile產生CZipOutputStream.class及CZipInputStream.class,使用winzip開啟[java_home]/jre/lib/rt.jar這個檔案,將CZipOutputStream.class及CZipInputStream.class加進去,記得「Save full path info」一定要打勾。
以後當壓縮及解壓縮時有中文檔名及路徑的問題時,就可以指定編碼方式來處理了。

CZipOutputStream zos=new CZipOutputStream(OutputStream os,String encoding);
CZipInputStream zins=new CZipInputStream(InputStream ins,String encoding);
以「壓縮與解壓縮(1)」為例:
FileOutputStream fos =new FileOutputStream(request.getRealPath("/")+"myzip.zip");
CZipOutputStream zos=new CZipOutputStream(fos,"GBK");
其他地方都不用改,便可以處理中文檔名的壓縮。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.