ZipInputStream解压有中文名的zip包

ZipInputStream解压有中文名的zip包
2008-08-01 13:36
下午闲来没事做,就想解决一下很久以前的一个问题,那就是java.util.zip.ZipInputStream解压文件的时候,如果包里有中 文名的文件,那报错,弄了一会儿,竟然解决了,不用像以前在网上查到的要重新编译jdk的。(jdk:sun jdk1.4.2)

1.重建zip包

新建一个自己的zip包,比如com.agile.zip,在这个包中把要用到的类从jdk的源码里放到这里,用eclipse可以很同快地完成这 个工作。需要所类 有:DeflaterOutputStream,InflaterInputStream,ZipConstants,ZipEntry,ZipInputStream,ZipOutputStream

上面这些类在放到com.aigle.zip包中后,在Eclipse中会显示出一些错误,这里要做得就是更改import以及其它一些工作,惟一的目的就是通过编译,不再出现编译错误。

2.修改ZipInputStream

ZipInputStream这个类中,需要修改getUTF8String这个方法,经过试验,用winRar压缩后的zip文件,其中的中文文件名是以gbk编码保存的,因此只需要在这个方法的前面加上

try {
String s = new String(b,off,len,"gbk");
return s;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
修改后的方法类似下面的代码:

private static String getUTF8String(byte[] b, int off, int len) {
try {
String s = new String(b,off,len,"gbk");
return s;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// First, count the number of characters in the sequence
int count = 0;
int max = off + len;

...

...

}

3.去掉一些本地调用方法

原来的java.util.zip.ZipEntry里面,要加载本地库,在这里这些代码是没有用处的,去掉就可以了,而如果不去掉,会引起链接错误,很奇怪,这几个native方法我也没有找到在哪儿使用了,sun的jdk1.4.2里留着它们做什么呢?

static {
/* load the zip library */
java.security.AccessController.doPrivileged(
new sun.security.action.LoadLibraryAction("zip"));
initIDs();
}

4.测试

代码:这里是我修改后的zip包

加入解压缩测试代码文件名为unziptest.java:
/**
*
*/
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;

import com.agile.zip.ZipEntry;
import com.agile.zip.ZipInputStream;
/**
* @author lianjzh
*
*/
public class unziptest {

static final int BUFFER = 2048;
public static void main(String argv[]) {
try {
unziptest uz=new unziptest();
String zippath = "d:\\unzip\\";// /解压到的目标文件路径
String zipDir = "d:\\abc.zip";// 要解压的压缩文件的存放路径

File file = new File(zipDir);

String realname = file.getName();
System.out.println(realname);
int end = realname.lastIndexOf(".");
System.out.println("要解压缩的文件名.........."+zipDir);
System.out.println("解压到的目录" +zippath);
uz.ReadZip(zippath,zipDir);

} catch (Exception e) {
e.printStackTrace();
}
}

public void ReadZip(String zippath, String unzipPath) throws Exception {
try {
BufferedOutputStream dest = null;
FileInputStream fis = new
FileInputStream(unzipPath);//"d:\\abc.zip"
ZipInputStream zis = new
ZipInputStream(new BufferedInputStream(fis));
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
System.out.println("Extracting: " + entry);
int count;
byte data[] = new byte[BUFFER];

if (entry.isDirectory())// 如果为目录条目,则返回 true,执行下列语句
{
System.out.println("Dir: " + entry.getName() + " skipped..");
continue;
}

int begin = unzipPath.lastIndexOf("\\") + 1;
int end = unzipPath.lastIndexOf(".");
String zipRealName = unzipPath.substring(begin, end);
// write the files to the

dest = new BufferedOutputStream(
new FileOutputStream(getRealFileName(zippath + "\\"
+ zipRealName, entry.getName())));



// FileOutputStream fos = new
// FileOutputStream(wholepath);


//dest = new
// BufferedOutputStream(fos, BUFFER);
while ((count = zis.read(data, 0, BUFFER))
!= -1) {
dest.write(data, 0, count);
}
dest.flush();
dest.close();
}
zis.close();
} catch (Exception e) {
e.printStackTrace();
}

}
/**
* 给定根目录,返回一个相对路径所对应的实际文件名.
*
* @param zippath
* 指定根目录
* @param absFileName
* 相对路径名,来自于ZipEntry中的name
* @return java.io.File 实际的文件
*/
private File getRealFileName(String zippath, String absFileName) {

String[] dirs = absFileName.split("/", absFileName.length());

File ret = new File(zippath);// 创建文件对象

if (dirs.length > 1) {
for (int i = 0; i < dirs.length - 1; i++) {
ret = new File(ret, dirs[i]);

}
}

if (!ret.exists()) {// 检测文件是否存在
ret.mkdirs();// 创建此抽象路径名指定的目录
}
ret = new File(ret, dirs[dirs.length - 1]);// 根据 ret 抽象路径名和 child
// 路径名字符串创建一个新 File 实例

return ret;
}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值