解压缩带有中文名文件的ZIP包

来源:互联网 发布:c语言布尔类型什么意思 编辑:程序博客网 时间:2024/05/22 07:02

java.util.zip.ZipInputStream和java.util.zip.ZipOutputStream压缩和解压带有中文名文件的ZIP包时,会报如下异常:

java.lang.IllegalArgumentException
 at java.util.zip.ZipInputStream.getUTF8String(ZipInputStream.java:293)
 at java.util.zip.ZipInputStream.readLOC(ZipInputStream.java:247)
 at java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:74)
 at com.test.ZipTest.unZipAssetSouce(ZipTest.java:25)
 at com.test.ZipTest.main(ZipTest.java:14)

原因是JDK自带的ZIP工具类,默认读取文件名采用的是UTF-8编码,而对于那些文件名以非UTF-8编码的文件将不能正确读入,如利用WinZip压缩的ZIP包将不能处理有中文名的文件,其采用的是ASCII编码的,而在开发中往往会遇到这样的问题,下面给出解决方案:

提取JDK内部几个处理ZIP相关的类,Deflater.java,DeflaterOutputStream.java,InflaterInputStream.java,ZipConstants.java,ZipEntry.java,ZipInputStram.java,然后自定义一个CompresszZipFile.java 读入ZIP文件,源码:

import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;public class CompresszZipFile {static final int BUFFER = 2048;/** * 读取ZIP文件,只适合于ZIP文件对于RAR文件无效,因为ZIP文件的压缩算法是公开的,而RAR不是 * @version 1.0 * @param zipfilepath:ZIP文件的路径,unzippath:要解压到的文件路径 */public void ReadZip(String zipfilepath,String unzippath){try {BufferedOutputStream bos = null;//创建输入字节流FileInputStream fis = new FileInputStream(zipfilepath);//根据输入字节流创建输入字符流BufferedInputStream bis = new BufferedInputStream(fis);//根据字符流,创建ZIP文件输入流ZipInputStream zis = new ZipInputStream(bis);//zip文件条目,表示zip文件ZipEntry entry;//循环读取文件条目,只要不为空,就进行处理while((entry=zis.getNextEntry())!=null){System.out.println("===="+entry.getName());int count ;byte date[] = new byte[BUFFER];//如果条目是文件目录,则继续执行if(entry.isDirectory()){continue;}else{int begin = zipfilepath.lastIndexOf("\\")+1;int end = zipfilepath.lastIndexOf(".")+1;String zipRealName = zipfilepath.substring(begin,end);bos = new BufferedOutputStream(new FileOutputStream(this.getRealFileName(unzippath+"\\"+zipRealName,entry.getName())));while((count=zis.read(date))!=-1){bos.write(date,0,count);}bos.flush();bos.close();}}zis.close();} catch (Exception e) {e.printStackTrace();}}private File getRealFileName(String zippath,String absFileName){String[] dirs = absFileName.split("/",absFileName.length());//创建文件对象 File file = new File(zippath);if(dirs.length>1){for(int i=0;i<dirs.length-1;i++){//根据file抽象路径和dir路径字符串创建一个新的file对象,路径为文件的上一个目录file = new File(file,dirs[i]);}}if(!file.exists()){file.mkdirs();}file = new File(file,dirs[dirs.length-1]);return file;}}

然后建立一个测试类 ZipTest.java,源码:

import com.zip.tool.CompresszZipFile;public class ZipTest {public static void main(String args[]){CompresszZipFile compress = new CompresszZipFile();compress.ReadZip("D:\\Android\\workspace\\Test\\word.zip", "D:\\test");}}

测试运行OK 。。。

为方便大家测试,将以上相关类打成一个jar包分享给大家!!(以上源码有些来源于网络)

http://download.csdn.net/download/adreamer_bj/3745253