随笔记录
Java文件压缩操作
2016-1-5 diaba


原文:http://hello-nick-xu.iteye.com/blog/2002613



     在web开发过程中,进行文件的压缩传输是一种常见的需求。比如一种场景:用户需要下载定时生成的报表,我们需要先对报表文件进行压以方便用户的下载,并减少文件的存储空间。

     事实上,JDK已经提供了文件压缩/解压缩的支持,可以生成zip/gzip的压缩格式,并且支持支持“校验和”以检查压缩文件的完整性。通常会使用CRC(循环冗余校验)算法进行校验。



     遗憾的是,JDK的文件压缩功能无法处理文件名称包含中文的问题。为此,我们需要用到ant.jar第三方开源支持包。



     如下所示代码,采用Junit 4进行压缩功能的测试:



 





Java代码  收藏代码




  1. /* 


  2.  * Copyright (c) 2014, hello_nick_xu@foxmail.com, All rights reserved. 


  3.  */  


  4. package com.test.zip;  


  5.   


  6. import java.io.BufferedInputStream;  


  7. import java.io.BufferedOutputStream;  


  8. import java.io.File;  


  9. import java.io.FileInputStream;  


  10. import java.io.FileOutputStream;  


  11. import java.util.zip.CRC32;  


  12. import java.util.zip.CheckedOutputStream;  


  13.   


  14. import org.apache.tools.zip.ZipEntry;  


  15. import org.apache.tools.zip.ZipOutputStream;  


  16. import org.junit.Test;  


  17.   


  18. /** 


  19.  * 功能简述: 进行文件压缩功能测试 


  20.  * @author Nick Xu 


  21.  */  


  22. public class ZipTest {  


  23.     //源文件夹  


  24.     private final String sourceDirStr = "E:/source";  


  25.     //目标文件  


  26.     private final String zipPath = "E:/dest.zip";  


  27.     //缓冲区大小设置  


  28.     private static final int BUFFER_SIZE = 1024;  


  29.   


  30.     /**  


  31.      * 功能简述: 普通压缩测试 


  32.      * @throws Exception 


  33.      */  


  34.     @Test  


  35.     public void testZip() throws Exception {  


  36.   


  37.         // zip输出流:使用缓冲流进行了包装  


  38.         ZipOutputStream zipOut = new ZipOutputStream(  


  39.             new BufferedOutputStream(  


  40.                 new FileOutputStream(zipPath), BUFFER_SIZE));  


  41.   


  42.         // 得到源文件夹下的文件列表  


  43.         File sourceDirectory = new File(sourceDirStr);  


  44.         File[] files = sourceDirectory.listFiles();  


  45.   


  46.         byte[] bs = new byte[BUFFER_SIZE];    // 缓冲数组  


  47.         int value = -1;   //文件是否结束标记  


  48.           


  49.         for (File file : files) { // 遍历所有的文件  


  50.             zipOut.putNextEntry(new ZipEntry(file.getName()));   // 存入文件名称,便于解压缩  


  51.             //文件读写  


  52.             BufferedInputStream bfInput = new BufferedInputStream(  


  53.                     new FileInputStream(file), BUFFER_SIZE);  


  54.             while ((value = bfInput.read(bs, 0, bs.length)) != -1) {  


  55.                 zipOut.write(bs, 0, value);  


  56.             }  


  57.             bfInput.close(); //关闭缓冲输入流  


  58.         }  


  59.         //关闭输出流  


  60.         zipOut.flush();  


  61.         zipOut.close();  


  62.     }  


  63.       


  64.     /**  


  65.      * 功能简述: 文件压缩测试,获取校验和 


  66.      * @throws Exception 


  67.      */  


  68.     @Test  


  69.     public void testZipWithCheckSum() throws Exception {  


  70.   


  71.         //被校验的输出流:使用CRC32校验算法  


  72.         CheckedOutputStream checkedOutput = new   


  73.             CheckedOutputStream(new BufferedOutputStream(  


  74.                 new FileOutputStream(zipPath), BUFFER_SIZE),new   


  75.                 CRC32());  


  76.         //使用ZipOutputStream进行包装  


  77.         ZipOutputStream zipOut = new ZipOutputStream(checkedOutput);  


  78.   


  79.         // 得到文件名称列表  


  80.         File sourceDirectory = new File(sourceDirStr);  


  81.         File[] files = sourceDirectory.listFiles();  


  82.   


  83.         // 读写文件  


  84.         byte[] bs = new byte[BUFFER_SIZE];  


  85.         int value = -1;  


  86.         for (File file : files) {  


  87.             BufferedInputStream bfInput = new BufferedInputStream(  


  88.                     new FileInputStream(file), BUFFER_SIZE);  


  89.             zipOut.putNextEntry(new ZipEntry(file.getName()));  


  90.             while ((value = bfInput.read(bs, 0, bs.length)) != -1) {  


  91.                 zipOut.write(bs, 0, value);  


  92.             }  


  93.             bfInput.close();  


  94.         }  


  95.         zipOut.flush();  


  96.         zipOut.close();  


  97.           


  98.         //获取校验和:用于校验文件的完整性  


  99.         long checkSum = checkedOutput.getChecksum().getValue();  


  100.         System.out.println("checkSum : " + checkSum);  


  101.     }  


  102. }  




 完整项目功能,参见附件

发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容