前言

之前实现过一版Java的zip
链接:https://leanote.zzzmh.cn/blog/post/5cac404e16199b2e40000035

之前这一版针对的是文件或者文件夹,压缩成Zip压缩包。
这个和服务器上在线生成压缩包的需求有点出入。
服务器上的内容是存数据库的,如果要先产生一个临时文件
再压缩成Zip,就会产生很多临时文件,需要在写清理脚本,设计上不合理。
在研究了Java8内置的zip包后,发现其实他本质就是一个OutputStream
所以理论上其实可以直接把String作为文本的内容压到Zip中的文件里,文件的路径和文件名都可以按需求指定



代码

  1. import java.io.*;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.zip.ZipEntry;
  7. import java.util.zip.ZipOutputStream;
  8. /**
  9. * @author zmh
  10. * @date 2020-01-07
  11. * <p>
  12. * 文件流转压缩包工具类
  13. */
  14. public class ZipUtils {
  15. /**
  16. * 缓存区大小
  17. */
  18. private static final int BUFFER_SIZE = 2 * 1024;
  19. /**
  20. * 压缩核心方法
  21. */
  22. private static void compress(ZipOutputStream zos, String path, String name, String data) throws Exception {
  23. byte[] buf = new byte[BUFFER_SIZE];
  24. zos.putNextEntry(new ZipEntry(path + name));
  25. int len;
  26. ByteArrayInputStream in = new ByteArrayInputStream(data.getBytes(GzipUtils.GZIP_ENCODE_UTF_8));
  27. while ((len = in.read(buf)) != -1) {
  28. zos.write(buf, 0, len);
  29. }
  30. zos.closeEntry();
  31. in.close();
  32. }
  33. /**
  34. * 文本直接转zip压缩成文件
  35. *
  36. * @param list -> map -> path 路径; name 文件名; data 具体文本内容;
  37. * @param out 传入输出流
  38. * @throws RuntimeException 抛出异常
  39. */
  40. public static void toZip(List<Map<String, String>> list, OutputStream out) throws RuntimeException {
  41. ZipOutputStream zos = null;
  42. try {
  43. zos = new ZipOutputStream(out);
  44. for (Map<String, String> map : list) {
  45. String path = map.get("path");
  46. String name = map.get("name");
  47. String data = map.get("data");
  48. compress(zos, path, name, data);
  49. }
  50. } catch (Exception e) {
  51. throw new RuntimeException("zip error from ZipUtils", e);
  52. } finally {
  53. if (zos != null) {
  54. try {
  55. zos.close();
  56. } catch (IOException e) {
  57. e.printStackTrace();
  58. }
  59. }
  60. }
  61. }
  62. public static void main(String[] args) throws Exception {
  63. List<Map<String, String>> list = new ArrayList<>();
  64. OutputStream outputStream = new FileOutputStream(new File("/home/zzzmh/Desktop/临时文件/test.zip"));
  65. Map<String,String> m1 = new HashMap(){{put("path","/f1/f2/f3/");put("name","1.txt");put("data","abcdefg");}};
  66. Map<String,String> m2 = new HashMap(){{put("path","/f1/f2/f3/f4/");put("name","2.txt");put("data","abcdefg");}};
  67. Map<String,String> m3 = new HashMap(){{put("path","");put("name","3.txt");put("data","abcdefg");}};
  68. list.add(m1);
  69. list.add(m2);
  70. list.add(m3);
  71. toZip(list, outputStream);
  72. if (outputStream != null) {
  73. outputStream.close();
  74. }
  75. }
  76. }


结果



END

补充:这里传入的参数OutputStream,可以用于生成本地文件的FileOutputStream ,也可以用于HttpServletResponseresponse里的 ServletOutputStream 用于网页端直接文件流下载