zoukankan      html  css  js  c++  java
  • 【转】Java实现将文件或者文件夹压缩成zip

    转自:https://www.cnblogs.com/zeng1994/p/7862288.html

      1 package com.guo.utils;
      2 
      3 import java.io.*;
      4 import java.util.ArrayList;
      5 import java.util.List;
      6 import java.util.zip.ZipEntry;
      7 import java.util.zip.ZipOutputStream;
      8 
      9 public class ZipUtils {
     10     private static final int  BUFFER_SIZE = 2 * 1024;
     11 
     12     /**
     13      * 压缩成ZIP 方法     * @param srcDir 压缩文件夹路径
     14      * @param out    压缩文件输出流
     15      * @param KeepDirStructure  是否保留原来的目录结构,true:保留目录结构;
     16      *                          false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     17      * @throws RuntimeException 压缩失败会抛出运行时异常
     18      */
     19     public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure)
     20             throws RuntimeException{
     21 
     22         long start = System.currentTimeMillis();
     23         ZipOutputStream zos = null ;
     24         try {
     25             zos = new ZipOutputStream(out);
     26             File sourceFile = new File(srcDir);
     27             compress(sourceFile,zos,sourceFile.getName(),KeepDirStructure);
     28             long end = System.currentTimeMillis();
     29             System.out.println("压缩完成,耗时:" + (end - start) +" ms");
     30         } catch (Exception e) {
     31             throw new RuntimeException("zip error from ZipUtils",e);
     32         }finally{
     33             if(zos != null){
     34                 try {
     35                     zos.close();
     36                 } catch (IOException e) {
     37                     e.printStackTrace();
     38                 }
     39             }
     40         }
     41 
     42     }
     43 
     44     /**
     45      * 压缩成ZIP 方法     * @param srcFiles 需要压缩的文件列表
     46      * @param out           压缩文件输出流
     47      * @throws RuntimeException 压缩失败会抛出运行时异常
     48      */
     49     public static void toZip(List<File> srcFiles , OutputStream out)throws RuntimeException {
     50         long start = System.currentTimeMillis();
     51         ZipOutputStream zos = null ;
     52         try {
     53             zos = new ZipOutputStream(out);
     54             for (File srcFile : srcFiles) {
     55                 byte[] buf = new byte[BUFFER_SIZE];
     56                 zos.putNextEntry(new ZipEntry(srcFile.getName()));
     57                 int len;
     58                 FileInputStream in = new FileInputStream(srcFile);
     59                 while ((len = in.read(buf)) != -1){
     60                     zos.write(buf, 0, len);
     61                 }
     62                 zos.closeEntry();
     63                 in.close();
     64             }
     65             long end = System.currentTimeMillis();
     66             System.out.println("压缩完成,耗时:" + (end - start) +" ms");
     67         } catch (Exception e) {
     68             throw new RuntimeException("zip error from ZipUtils",e);
     69         }finally{
     70             if(zos != null){
     71                 try {
     72                     zos.close();
     73                 } catch (IOException e) {
     74                     e.printStackTrace();
     75                 }
     76             }
     77         }
     78     }
     79 
     80 
     81     /**
     82      * 递归压缩方法
     83      * @param sourceFile 源文件
     84      * @param zos        zip输出流
     85      * @param name       压缩后的名称
     86      * @param KeepDirStructure  是否保留原来的目录结构,true:保留目录结构;
     87      *                          false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     88      * @throws Exception
     89      */
     90     private static void compress(File sourceFile, ZipOutputStream zos, String name,
     91                                  boolean KeepDirStructure) throws Exception{
     92         byte[] buf = new byte[BUFFER_SIZE];
     93         if(sourceFile.isFile()){
     94             // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
     95             zos.putNextEntry(new ZipEntry(name));
     96             // copy文件到zip输出流中
     97             int len;
     98             FileInputStream in = new FileInputStream(sourceFile);
     99             while ((len = in.read(buf)) != -1){
    100                 zos.write(buf, 0, len);
    101             }
    102             // Complete the entry
    103             zos.closeEntry();
    104             in.close();
    105         } else {
    106             //是文件夹
    107             File[] listFiles = sourceFile.listFiles();
    108             if(listFiles == null || listFiles.length == 0){
    109                 // 需要保留原来的文件结构时,需要对空文件夹进行处理
    110                 if(KeepDirStructure){
    111                     // 空文件夹的处理
    112                     zos.putNextEntry(new ZipEntry(name + "/"));
    113                     // 没有文件,不需要文件的copy
    114                     zos.closeEntry();
    115                 }
    116 
    117             }else {
    118                 for (File file : listFiles) {
    119                     // 判断是否需要保留原来的文件结构
    120                     if (KeepDirStructure) {
    121                         // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
    122                         // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
    123                         compress(file, zos, name + "/" + file.getName(),KeepDirStructure);
    124                     } else {
    125                         compress(file, zos, file.getName(),KeepDirStructure);
    126                     }
    127 
    128                 }
    129             }
    130         }
    131     }
    132 
    133     public static void main(String[] args) throws Exception {
    134         /** 测试压缩方法 */
    135         FileOutputStream fos1= new FileOutputStream(new File("E:/testZip.zip"));
    136         ZipUtils.toZip("E:/testZip", fos1,true);
    137 
    138         /** 测试压缩方法 */
    139         List<File> fileList = new ArrayList<>();
    140         fileList.add(new File("D:/Java/jdk1.7.0_45_64bit/bin/jar.exe"));
    141         fileList.add(new File("D:/Java/jdk1.7.0_45_64bit/bin/java.exe"));
    142         FileOutputStream fos2= new FileOutputStream(new File("c:/mytest02.zip"));
    143         ZipUtils.toZip(fileList, fos2);
    144     }
    145 }

    注意点:

    1. 文件和文件夹的压缩,通过递归的compress方法来实现,从最深的一层开始。
    2. 如果是文件夹,在传name时,需要在前面带一个“/”。表示是文件夹。 
      第123行:compress(file, zos, name + "/" + file.getName(),KeepDirStructure);
    3. 空文件夹要保留,也是通过后面加“/”。
    4. 压缩包中的文件,通过ZipEntry对象来添加,添加完之后,需要通过流的closeEntry()来关闭。
    5. web项目中,把response写到返回流中就行。
  • 相关阅读:
    MTK 官方 openwrt SDK 使用
    PF_RING packet overwrites
    pycares cffi
    libevent evbuffer bug
    浮点转字符串性能比较
    重写 libev 的 EV_WIN32_HANDLE_TO_FD
    thrift TNonblockingServer 使用
    accel-pptp 部署
    boost::asio 使用 libcurl
    蜂鸟A20开发板刷 cubietruck 的 SD 卡固件
  • 原文地址:https://www.cnblogs.com/amibandoufu/p/10799191.html
Copyright © 2011-2022 走看看