解压zip压缩包中的指定文件(害死人的错误)

简介:

使用Java 解压zip压缩包中的指定文件时遇到了问题。

且听我细细道来:

主要方法如下:

Java代码   收藏代码
  1. public static byte[] getContent2(final ZipFile zipFile, final ZipEntry zipEntry)  
  2.             throws IOException {  
  3.         InputStream inputStream = zipFile.getInputStream(zipEntry);  
  4.         int length = inputStream.available();  
  5.         byte[] bytes = new byte[length];  
  6.         inputStream.read(bytes);  
  7.         inputStream.close();  
  8.         return bytes;  
  9.     }  

 测试方法如下:

Java代码   收藏代码
  1. @Test  
  2.     public void test_getContent() throws ZipException, IOException{  
  3.         String outPutFileStr="d:\\Temp\\a\\test.zip";  
  4.         File file=new File(outPutFileStr);  
  5.         ZipFile zipFile = new ZipFile(file);  
  6.         ZipEntry zipEntry = zipFile.getEntry("BaiduYunGuanjia_2.1.022333.exe");  
  7.         byte[]bytes=ZipUtil.getContent2(zipFile, zipEntry);  
  8.         FileUtils.writeBytesToFile(bytes, "d:\\Temp\\a\\baidu.exe");  
  9.     }  

 说明:d:\\Temp\\a\\test.zip是zip压缩包,其中包含文件BaiduYunGuanjia_2.1.022333.exe。我解压的步骤是这样的:

我先通过ZipUtil.getContent2 方法获取BaiduYunGuanjia_2.1.022333.exe 的字节数组,再把该字节数组写入文件d:\\Temp\\a\\baidu.exe。

执行完之后,发现解压的文件不正确,也就是d:\\Temp\\a\\baidu.exe 与BaiduYunGuanjia_2.1.022333.exe的MD5不同。

问题到底出在哪里呢?

getContent2 方法我反复看了无数遍,也没有看出问题。

 

后来终于找到了原因:getContent2方法的第四行得到的length,但是第六行inputStream.read(bytes);读取的字节数并不是length。可以通过inputStream.read(bytes)的返回值获取真正读取的字节个数。

解决方法:

getContent2改进如下:

Java代码   收藏代码
  1. /** 
  2.      * 从zip包中读取给定文件名的内容 
  3.      *  
  4.      * @param zipFile 
  5.      * @param zipEntry 
  6.      * @return 
  7.      * @throws IOException 
  8.      */  
  9.     public static byte[] getContent(final ZipFile zipFile,  
  10.             final ZipEntry zipEntry) throws IOException {  
  11.         InputStream inputStream = zipFile.getInputStream(zipEntry);  
  12.         byte[] buffer = new byte[1024];  
  13.         byte[] bytes = new byte[0];  
  14.         int length;  
  15.         while ((length = (inputStream.read(buffer))) != -1) {  
  16.             byte[] readBytes = new byte[length];  
  17.             System.arraycopy(buffer, 0, readBytes, 0, length);  
  18.             bytes = SystemUtil.mergeArray(bytes, readBytes);  
  19.         }  
  20.         inputStream.close();  
  21.         return bytes;  
  22.     }  

 测试方法:

Java代码   收藏代码
  1. @Test  
  2.     public void test_getContent() throws ZipException, IOException{  
  3.         String outPutFileStr="d:\\Temp\\a\\test.zip";  
  4.         File file=new File(outPutFileStr);  
  5.         ZipFile zipFile = new ZipFile(file);  
  6.         ZipEntry zipEntry = zipFile.getEntry("BaiduYunGuanjia_2.1.022333.exe");  
  7.         byte[]bytes=ZipUtil.getContent(zipFile, zipEntry);  
  8.         FileUtils.writeBytesToFile(bytes, "d:\\Temp\\a\\baidu.exe");  
  9.     }  

 

终于ok了。

相关文章
|
5月前
|
Java
Java实现多文件打包成压缩包下载
Java实现多文件打包成压缩包下载
154 0
|
11月前
|
PHP
thinkphp图片打包到zip压缩包下载
thinkphp图片打包到zip压缩包下载
146 0
|
1月前
|
算法 Python Windows
Python实现文件压缩和解压功能
Python实现文件压缩和解压功能
28 0
|
8月前
|
存储
水滴文件打包上传报错【解决方法】
水滴文件打包上传报错【解决方法】
60 0
|
8月前
|
Linux
Linux常用的压缩与解压
1、gzip压缩解压 因为都是系统自带的我们不需要安装; ls 看一下目录当前的文件,创建一个 touch 123.txt 文件; 原文件消失,压缩解压 gzip 进行压缩,(“ gzip 123.txt ”),这样就压缩完毕了; gzip 进行解压,(“ gzip -d 123.txt.gz”),这样就解压完毕了; 原文件保留,gzip -k 123.txt、gzip -dk 123.txt.gz ; 2、bzip2压缩解压 因为都是系统自带的我们不需要安装; 原文件消失,压缩解压 bzip2进行压缩,(“ bzip2 123.txt ”),这样就压缩完毕了; bzip2 进行解压,(“
55 0
|
Python
Python编程:运行目录或zip压缩文件
Python编程:运行目录或zip压缩文件
93 0
|
SQL Shell Linux
zip 包自动解压缩脚本 | 学习笔记
快速学习 zip 包自动解压缩脚本
157 0
|
SQL IDE Shell
zip包自动解压缩脚本 | 学习笔记
快速学习zip包自动解压缩脚本
484 0
Java把文件压缩成.zip压缩包和解压.zip压缩包
Java把文件压缩成.zip压缩包和解压.zip压缩包
236 1
|
Java 缓存 存储
java下载多文件夹的文件最终打zip包返回给用户
业务需求,需要做一个导出用户单据图片的功能,需求为:按单据单号分文件夹分别存储单据的图片!最终导出zip包给用户。通过网上各种找代码,写出一个小demo,供各位看官学习! // 假装是一个单据集合 List<String> imgUrls = new ArrayList<>(); imgUrls.
4350 0