Java压缩和解压文件工具类ZipUtil

来源:互联网 发布:快速瘦大腿 知乎 编辑:程序博客网 时间:2024/05/20 06:36
[java] view plain copy
  1. </pre><pre code_snippet_id="1837335" snippet_file_name="blog_20160818_2_1853501" name="code" class="java">packagecom.utility.zip;  
  2.    
  3. importjava.io.BufferedInputStream;  
  4. importjava.io.BufferedOutputStream;  
  5. importjava.io.File;  
  6. importjava.io.FileInputStream;  
  7. importjava.io.FileOutputStream;  
  8. importjava.io.IOException;  
  9. importjava.util.zip.ZipEntry;  
  10. importjava.util.zip.ZipInputStream;  
  11. importjava.util.zip.ZipOutputStream;  
  12.    
  13. importcom.utility.io.IOUtil;  
  14.    
  15. /** 
  16.  * 通过Java的Zip输入输出流实现压缩和解压文件 
  17.  * 
  18.  * @author liujiduo 
  19.  * 
  20.  */  
  21. publicfinal class ZipUtil {  
  22.    
  23.     privateZipUtil() {  
  24.         // empty  
  25.     }  
  26.    
  27.     /** 
  28.      * 压缩文件 
  29.      * 
  30.      * @param filePath 
  31.      *            待压缩的文件路径 
  32.      * @return 压缩后的文件 
  33.      */  
  34.     publicstatic File zip(String filePath) {  
  35.         File target = null;  
  36.         File source = newFile(filePath);  
  37.         if(source.exists()) {  
  38.             // 压缩文件名=源文件名.zip  
  39.             String zipName = source.getName() + ".zip";  
  40.             target = newFile(source.getParent(), zipName);  
  41.             if(target.exists()) {  
  42.                 target.delete();// 删除旧的文件  
  43.             }  
  44.             FileOutputStream fos = null;  
  45.             ZipOutputStream zos = null;  
  46.             try{  
  47.                 fos = newFileOutputStream(target);  
  48.                 zos = newZipOutputStream(newBufferedOutputStream(fos));  
  49.                 // 添加对应的文件Entry  
  50.                 addEntry("/", source, zos);  
  51.             }catch(IOException e) {  
  52.                 thrownew RuntimeException(e);  
  53.             }finally{  
  54.                 IOUtil.closeQuietly(zos, fos);  
  55.             }  
  56.         }  
  57.         returntarget;  
  58.     }  
  59.    
  60.     /** 
  61.      * 扫描添加文件Entry 
  62.      * 
  63.      * @param base 
  64.      *            基路径 
  65.      * 
  66.      * @param source 
  67.      *            源文件 
  68.      * @param zos 
  69.      *            Zip文件输出流 
  70.      * @throws IOException 
  71.      */  
  72.     privatestatic void addEntry(String base, File source, ZipOutputStream zos)  
  73.             throwsIOException {  
  74.         // 按目录分级,形如:/aaa/bbb.txt  
  75.         String entry = base + source.getName();  
  76.         if(source.isDirectory()) {  
  77.             for(File file : source.listFiles()) {  
  78.                 // 递归列出目录下的所有文件,添加文件Entry  
  79.                 addEntry(entry + "/", file, zos);  
  80.             }  
  81.         }else{  
  82.             FileInputStream fis = null;  
  83.             BufferedInputStream bis = null;  
  84.             try{  
  85.                 byte[] buffer = newbyte[102410];  
  86.                 fis = newFileInputStream(source);  
  87.                 bis = newBufferedInputStream(fis, buffer.length);  
  88.                 intread = 0;  
  89.                 zos.putNextEntry(newZipEntry(entry));  
  90.                 while((read = bis.read(buffer, 0, buffer.length)) != -1) {  
  91.                     zos.write(buffer,0, read);  
  92.                 }  
  93.                 zos.closeEntry();  
  94.             }finally{  
  95.                 IOUtil.closeQuietly(bis, fis);  
  96.             }  
  97.         }  
  98.     }  
  99.    
  100.     /** 
  101.      * 解压文件 
  102.      * 
  103.      * @param filePath 
  104.      *            压缩文件路径 
  105.      */  
  106.     publicstatic void unzip(String filePath) {  
  107.         File source = newFile(filePath);  
  108.         if(source.exists()) {  
  109.             ZipInputStream zis = null;  
  110.             BufferedOutputStream bos = null;  
  111.             try{  
  112.                 zis = newZipInputStream(newFileInputStream(source));  
  113.                 ZipEntry entry = null;  
  114.                 while((entry = zis.getNextEntry()) != null  
  115.                         && !entry.isDirectory()) {  
  116.                     File target = newFile(source.getParent(), entry.getName());  
  117.                     if(!target.getParentFile().exists()) {  
  118.                         // 创建文件父目录  
  119.                         target.getParentFile().mkdirs();  
  120.                     }  
  121.                     // 写入文件  
  122.                     bos = newBufferedOutputStream(newFileOutputStream(target));  
  123.                     intread = 0;  
  124.                     byte[] buffer = newbyte[102410];  
  125.                     while((read = zis.read(buffer, 0, buffer.length)) != -1) {  
  126.                         bos.write(buffer,0, read);  
  127.                     }  
  128.                     bos.flush();  
  129.                 }  
  130.                 zis.closeEntry();  
  131.             }catch(IOException e) {  
  132.                 thrownew RuntimeException(e);  
  133.             }finally{  
  134.                 IOUtil.closeQuietly(zis, bos);  
  135.             }  
  136.         }  
  137.     }  
  138.    
  139.     publicstatic void main(String[] args) {  
  140.         String targetPath = "E:\\Win7壁纸";  
  141.         File file = ZipUtil.zip(targetPath);  
  142.         System.out.println(file);  
  143.         ZipUtil.unzip("F:\\Win7壁纸.zip");  
  144.     }  
  145. }  
  146.   
  147. packagecom.utility.io;  
  148.    
  149. importjava.io.Closeable;  
  150. importjava.io.IOException;  
  151.    
  152. /** 
  153.  * IO流工具类 
  154.  * 
  155.  * @author liujiduo 
  156.  * 
  157.  */  
  158. publicclass IOUtil {  
  159.     /** 
  160.      * 关闭一个或多个流对象 
  161.      * 
  162.      * @param closeables 
  163.      *            可关闭的流对象列表 
  164.      * @throws IOException 
  165.      */  
  166.     publicstatic void close(Closeable... closeables) throwsIOException {  
  167.         if(closeables != null) {  
  168.             for(Closeable closeable : closeables) {  
  169.                 if(closeable != null) {  
  170.                     closeable.close();  
  171.                 }  
  172.             }  
  173.         }  
  174.     }  
  175.    
  176.     /** 
  177.      * 关闭一个或多个流对象 
  178.      * 
  179.      * @param closeables 
  180.      *            可关闭的流对象列表 
  181.      */  
  182.     publicstatic void closeQuietly(Closeable... closeables) {  
  183.         try{  
  184.             close(closeables);  
  185.         }catch(IOException e) {  
  186.             // do nothing  
  187.         }  
  188.     }  
  189.    
  190. }  

用于服务器端打包文件的,将压缩后的文件写入到response输出流即可实现在服务器端打包下载,支持多级目录嵌套。
测试时可以先用ZipUtil.zip压缩某个文件夹test,得到压缩文件test.zip,然后将文件夹test删除,用ZipUtil.unzip解压test.zip即可还原。

PS:需要解决中文乱码的朋友可以参考此处 http://log-cd.iteye.com/blog/585647