解决ZipInputStream不能正确处理中文文件名

我们知道,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");
其他地方都不用改,便可以处理中文档名的压缩。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ZipInputStream是Java中用来解压ZIP文件的类,它可以逐个读取ZIP文件中的每个文件项。当遇到中文文件名时,需要进行特殊处理。 ZIP文件内部使用的是一种编码方式,称为CP437,它是一种针对英文字符的编码。而中文字符在ZIP文件无法被直接表示。 当我们使用ZipInputStream读取ZIP文件中的文件名时,需要判断文件名是否为中文。一种常见的方式是通过判断文件名的编码方式来区分中文文件名和英文文件名。 对于中文文件名,可以使用以下步骤进行处理: 1. 使用ZipInputStream的getNextEntry()方法获取下一个文件项。 2. 获取文件名字节流。 3. 判断文件名字节流的编码方式,如果是CP437编码,说明是英文文件名,直接将字节流转换为字符串即可。 4. 如果不是CP437编码,说明是中文文件名,需要将字节流按照指定的编码方式(如UTF-8)转换为字符串。 5. 完成处理后,可以对该文件进行其他操作,例如读取文件内容或者保存文件。 需要注意的是,中文字符的编码方式可能不止一种,因此在转换过程中,需要使用与ZIP文件内部编码方式一致的编码方式进行转换,以免出现乱码问题。 总之,当遇到中文文件名时,在使用ZipInputStream解压ZIP文件时,需要先判断文件名的编码方式,然后使用正确的编码方式对中文文件名进行转换,以确保正确读取和处理中文文件名
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值