转自: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. * @param sourceFile 源文件
  83. * @param zos zip输出流
  84. * @param name 压缩后的名称
  85. * @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构;
  86. * false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
  87. * @throws Exception
  88. */
  89. private static void compress(File sourceFile, ZipOutputStream zos, String name,
  90. boolean KeepDirStructure) throws Exception{
  91. byte[] buf = new byte[BUFFER_SIZE];
  92. if(sourceFile.isFile()){
  93. // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
  94. zos.putNextEntry(new ZipEntry(name));
  95. // copy文件到zip输出流中
  96. int len;
  97. FileInputStream in = new FileInputStream(sourceFile);
  98. while ((len = in.read(buf)) != -1){
  99. zos.write(buf, 0, len);
  100. }
  101. // Complete the entry
  102. zos.closeEntry();
  103. in.close();
  104. } else {
  105. //是文件夹
  106. File[] listFiles = sourceFile.listFiles();
  107. if(listFiles == null || listFiles.length == 0){
  108. // 需要保留原来的文件结构时,需要对空文件夹进行处理
  109. if(KeepDirStructure){
  110. // 空文件夹的处理
  111. zos.putNextEntry(new ZipEntry(name + "/"));
  112. // 没有文件,不需要文件的copy
  113. zos.closeEntry();
  114. }
  115.  
  116. }else {
  117. for (File file : listFiles) {
  118. // 判断是否需要保留原来的文件结构
  119. if (KeepDirStructure) {
  120. // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
  121. // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
  122. compress(file, zos, name + "/" + file.getName(),KeepDirStructure);
  123. } else {
  124. compress(file, zos, file.getName(),KeepDirStructure);
  125. }
  126.  
  127. }
  128. }
  129. }
  130. }
  131.  
  132. public static void main(String[] args) throws Exception {
  133. /** 测试压缩方法 */
  134. FileOutputStream fos1= new FileOutputStream(new File("E:/testZip.zip"));
  135. ZipUtils.toZip("E:/testZip", fos1,true);
  136.  
  137. /** 测试压缩方法 */
  138. List<File> fileList = new ArrayList<>();
  139. fileList.add(new File("D:/Java/jdk1.7.0_45_64bit/bin/jar.exe"));
  140. fileList.add(new File("D:/Java/jdk1.7.0_45_64bit/bin/java.exe"));
  141. FileOutputStream fos2= new FileOutputStream(new File("c:/mytest02.zip"));
  142. ZipUtils.toZip(fileList, fos2);
  143. }
  144. }

注意点:

  1. 文件和文件夹的压缩,通过递归的compress方法来实现,从最深的一层开始。
  2. 如果是文件夹,在传name时,需要在前面带一个“/”。表示是文件夹。 
    1. 123行:compress(file, zos, name + "/" + file.getName(),KeepDirStructure);
  3. 空文件夹要保留,也是通过后面加“/”。
  4. 压缩包中的文件,通过ZipEntry对象来添加,添加完之后,需要通过流的closeEntry()来关闭。
  5. web项目中,把response写到返回流中就行。

【转】Java实现将文件或者文件夹压缩成zip的更多相关文章

  1. Java实现将文件或者文件夹压缩成zip

            最近碰到个需要下载zip压缩包的需求,于是我在网上找了下别人写好的zip工具类.但找了好多篇博客,总是发现有bug.因此就自己来写了个工具类.         这个工具类的功能为: ( ...

  2. 【转】java导出多个excel表格,并压缩成zip输出

    转自:http://blog.csdn.net/qq_14861089/article/details/53169414    感谢作者分享 /** * 导出支付宝批量支付文件excel * * @p ...

  3. java实现将文件压缩成zip格式

    以下是将文件压缩成zip格式的工具类(复制后可以直接使用): zip4j.jar包下载地址:http://www.lingala.net/zip4j/download.php package util ...

  4. 使用ICSharpZipLib将文件夹压缩为zip文件

    序言:     在我接触Git和SVN之前,我最常用的保存数据的办法就是把文件夹压缩成一个zip文件,添加上时间戳.下面是我在学习C#的文件操作之后做的一个练习,使用开源的ICSharpZipLib来 ...

  5. vue-webpack项目自动打包压缩成zip文件批处理

    为什么需要这个? 使用vue框架开发项目,npm run build这个命令会一直用到,如果需要给后端发包,那你还要打包成zip格式的压缩包,特别是项目提测的时候,一天可能要执行重复好几次,所以才有了 ...

  6. linux下压缩成zip文件解压zip文件

    linux  zip命令的基本用法是: zip [参数] [打包后的文件名] [打包的目录路径] linux  zip命令参数列表: -a     将文件转成ASCII模式 -F     尝试修复损坏 ...

  7. java 实现Excel压缩成Zip导出

    1 概述 在web项目中常见的一种场景就是将文件导出为Excel,但是当需要导出多个Excel时,使用者将频繁操作,这样就严重降低了项目的友好交互性以及易用性,那么怎么才能优雅的解决这个问题呢?笔者今 ...

  8. PPT文件流转为图片,并压缩成ZIP文件输出到指定目录

    实现流程: 接收InputStream流->复制流->InputStream流转为PPT->PPT转为图片->所有图片压缩到一个压缩文件下 注意: 1.PPT文件分为2003和 ...

  9. Vue -- webpack 项目自动打包压缩成zip文件

    这段时间用 Vue2.0 开发项目,每次打包都会用到 npm run build 命令,但是每次部署时给后端发包都要手动zip压缩,这样一两次还行,但遇到项目板块测试和临时加急功能测试的时候,一天可能 ...

随机推荐

  1. sql语句在Mysql中如何执行?

    1.MySQL 主要分为 Server 层和引擎层,Server 层主要包括连接器.查询缓存.分析器.优化器.执行器,同时还有一个日志模块(binlog),这个日志模块所有执行引擎都可以共用,redo ...

  2. linux网络编程中的shutdown()与close()函数

    1.close()函数 int close(int sockfd); //返回成功为0,出错为-1 close 一个套接字的默认行为是把套接字标记为已关闭,然后立即返回到调用进程,该套接字不能再由cl ...

  3. 【转】使用Python中HTTPParser模块进行简单的html解析

    http://www.cnblogs.com/coser/archive/2012/01/09/2317076.html

  4. Objective-C 2.0 基础要点归纳

    本文的阅读基本条件: 具备C/C++基础知识,了解面向对象特征 阅读过<Objective-C 2.0 程序设计(第二版)>.<Objective-C 程序设计 第6版>或相关 ...

  5. Django打造大型企业官网(一)

    一.nvm的安装 (1)下载:nvm1.16 (2)安装完成后添加环境变量 C:\Users\Administrator\AppData\Roaming\nvm (3)修改settings.txt,将 ...

  6. Android oat文件提取转换

    说明: 1.手机厂商可以修改Android源码并进行编译后再生成oat格式文件在手机上存储,比如boot-okhttp.oat,boot-framework.oat. 2.自带的apk可以调用这些模块 ...

  7. 深入浅出Hibernate(二)多对一关系映射

    学习Hibernate是为了更方便的操作数据库,在数据库中的关系模型中存在多对一的关系,比方下图所看到的的员工和部门之间的关系,那么这样的关系在Hibernate中怎样映射呢?让我用一个小Demo来具 ...

  8. 【bzoj1798】[Ahoi2009]Seq 维护序列seq

    大意:一个数组,三个操作,第一种是区间[a,b]每个数乘乘,第二种是区间[a,b]每个数加c,第三种是查询[a,b]区间的和并对p取摸. 两种操作就不能简单的只往下传标记.每次传乘法标记时,要把加法标 ...

  9. 公钥加密,摘要算法MD5,SSH相关概念

    1.公钥加密,又叫非对称加密,一般指的是用一组密钥来保证通信的安全.(公钥,私钥)成对存在且惟一,典型的公钥算法有 RSA(计算出的是1024位,128字节),顺便提一下与公钥加密算法相对应的就是传统 ...

  10. 【Poj 1832】连环锁

    连环锁 Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1260   Accepted: 403 Description 许多 ...