需求

java实现文件zip压缩,方便客户端下载。
方法1 单个或多个文件压缩成压缩包
方法2 整个文件夹按照原路径格式压缩成压缩包

代码

找了个大神的代码,亲测java8完美运行,稍加修改方便项目里调用
参考:https://www.cnblogs.com/zeng1994/p/7862288.html

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