在Java应用程序中,对文字的编码是以unicode为基础的,压缩、解压的文件名,也是以unicode来编码的,然而,在现今市面上的大部分压缩软件,比如winzip、winrar等,不支持unicode的编码方式,因而用Java软件压缩后的中文文件名显示出来是乱码。
对文件的压缩和解压是通过ZipInputStream和ZipOutputStream类来完成,通过修改这两个类的编码方式,可以对中文文件名进行处理。
2.1 ZipOutputStream的处理
从JDK的src.zip取得ZipOutputStream.java源代码(通常在JDK的安装目录下),另存为CNZipOutputStream.java。
修改源代码,将Class名称改为CNZipOutputStream,构造函数名称也要更改。增加成员变量,用来记录编码方式。Private String encoding=”UTF -8” ;增加一个新的构造函数,在实例话时可以指定编码方式。
public CNZipOutputStream(OutputStream out,String encoding){
super(out,new Deflater(Deflater.DEFAULT_COMPRESSION,true));
usesDefaultDeflater=true;
this.encoding=encoding;
}
找到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);
}
2.2 ZipInputStream的处理
从JDK的src.zip取得ZipInputStream.java源代码(通常在JDK的安装目录下),另存为CNZipInputStream.java。
修改源代码,将Class名称改为CNZipInputStream,构造函数名称也要更改。增加成员变量,用来记录编码方式。Private String encoding=”UTF -8” ;增加一个新的构造函数,在实例话时可以指定编码方式。
public CNZipInputStream(InputStream in) {
super(new PushbackInputStream(in, 512), new Inflater(true), 512);
usesDefaultInflater = true;
if(in == null) {
throw new NullPointerException("in is null");
}
}
找到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));
}
也可以利用开源的 Apache 项目提供的 ant.jar 包来压缩 中文名称的文件 ,下载 URL 地址为 http://ant.apache.org/ ,下载 ant 源文件 apache-ant- 1.7.0 -src.zip ,解压后在 org 包里有实现 zip 压缩的全部 java 源文件,利用 import org.apache.tools.zip.* 命令导入这些类文件即可。 ant.jar 提供的 ZIP 压缩类解决了 中文名称文件压缩的乱码问题。