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

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文件,源码:

  1. import java.io.BufferedInputStream;  
  2. import java.io.BufferedOutputStream;  
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileOutputStream;  
  6.   
  7. public class CompresszZipFile {  
  8.       
  9.     static final int BUFFER = 2048;  
  10.     /** 
  11.      * 读取ZIP文件,只适合于ZIP文件对于RAR文件无效,因为ZIP文件的压缩算法是公开的,而RAR不是 
  12.      * @version 1.0 
  13.      * @param zipfilepath:ZIP文件的路径,unzippath:要解压到的文件路径 
  14.      */  
  15.     public void ReadZip(String zipfilepath,String unzippath){  
  16.           
  17.         try {  
  18.             BufferedOutputStream bos = null;  
  19.             //创建输入字节流   
  20.             FileInputStream fis = new FileInputStream(zipfilepath);  
  21.             //根据输入字节流创建输入字符流   
  22.             BufferedInputStream bis = new BufferedInputStream(fis);  
  23.             //根据字符流,创建ZIP文件输入流   
  24.             ZipInputStream zis = new ZipInputStream(bis);  
  25.             //zip文件条目,表示zip文件   
  26.             ZipEntry entry;  
  27.             //循环读取文件条目,只要不为空,就进行处理   
  28.             while((entry=zis.getNextEntry())!=null){  
  29.                 System.out.println("===="+entry.getName());  
  30.                 int count ;  
  31.                 byte date[] = new byte[BUFFER];  
  32.                 //如果条目是文件目录,则继续执行   
  33.                 if(entry.isDirectory()){  
  34.                     continue;  
  35.                 }else{  
  36.                     int begin = zipfilepath.lastIndexOf("\\")+1;  
  37.                     int end = zipfilepath.lastIndexOf(".")+1;  
  38.                     String zipRealName = zipfilepath.substring(begin,end);  
  39.                     bos = new BufferedOutputStream(new FileOutputStream(this.getRealFileName(unzippath+"\\"+zipRealName,entry.getName())));  
  40.                     while((count=zis.read(date))!=-1){  
  41.                         bos.write(date,0,count);  
  42.                     }  
  43.                     bos.flush();bos.close();  
  44.                 }     
  45.             }  
  46.             zis.close();  
  47.         } catch (Exception e) {  
  48.             e.printStackTrace();  
  49.         }  
  50.     }  
  51.       
  52.     private File getRealFileName(String zippath,String absFileName){  
  53.         String[] dirs = absFileName.split("/",absFileName.length());  
  54.         //创建文件对象    
  55.         File file = new File(zippath);  
  56.         if(dirs.length>1){  
  57.             for(int i=0;i<dirs.length-1;i++){  
  58.                 //根据file抽象路径和dir路径字符串创建一个新的file对象,路径为文件的上一个目录   
  59.                 file = new File(file,dirs[i]);  
  60.             }  
  61.         }  
  62.         if(!file.exists()){  
  63.             file.mkdirs();  
  64.         }  
  65.         file = new File(file,dirs[dirs.length-1]);  
  66.         return file;  
  67.     }  
  68. }  
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,源码:

  1. import com.zip.tool.CompresszZipFile;  
  2.   
  3. public class ZipTest {  
  4.   
  5.     public static void main(String args[]){  
  6.           
  7.         CompresszZipFile compress = new CompresszZipFile();  
  8.         compress.ReadZip("D:\\Android\\workspace\\Test\\word.zip""D:\\test");  
  9.     }  
  10. }  
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

转自http://blog.csdn.net/adreamer_bj/article/details/6926036

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
解压缩zip文件中含有中文名文件时,可能会出现乱码或者解压失败的问题。这是因为在压缩文件时,文件名使用了默认编码格式,而在解压缩时,解压软件使用了不同的编码格式,导致文件名解析错误。 为了解决这个问题,可以通过指定解压缩文件名的编码格式来解决。以下是一个Java程序示例,用于解压缩zip文件并处理中文文件名的编码问题: ```java import java.io.*; import java.util.*; import java.util.zip.*; public class ZipUtils { public static void unzip(File zipFile, File destDir, String charset) throws IOException { if (!destDir.exists()) { destDir.mkdirs(); } ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFile), Charset.forName(charset)); ZipEntry entry; byte[] buffer = new byte[1024]; while ((entry = zipIn.getNextEntry()) != null) { String fileName = entry.getName(); if (entry.isDirectory()) { File subDir = new File(destDir, fileName); subDir.mkdirs(); continue; } File file = new File(destDir, fileName); File parent = file.getParentFile(); if (!parent.exists()) { parent.mkdirs(); } OutputStream out = new FileOutputStream(file); int len; while ((len = zipIn.read(buffer)) > 0) { out.write(buffer, 0, len); } out.close(); } zipIn.close(); } } ``` 在调用此方法时,可以指定解压缩文件名的编码格式,例如: ```java ZipUtils.unzip(new File("sun.zip"), new File("destDir"), "GBK"); ``` 这里的编码格式使用了GBK,根据实际情况可以修改为其他编码格式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值