且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-07-06 09:43:51

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

且听我细细道来:

主要方法如下:

Java代码  解压zip压缩包中的指定文件(害死人的错误)
  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代码  解压zip压缩包中的指定文件(害死人的错误)
  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代码  解压zip压缩包中的指定文件(害死人的错误)
  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代码  解压zip压缩包中的指定文件(害死人的错误)
  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了。