Java实现压缩解压文件

我会带着你远行 2022-12-11 09:14 301阅读 0赞

关键词:ZipOutputStream ZipInoutStream


最近在工作中有需求需要在浏览器中一次性下载多个文件,于是想到了使用压缩的功能。百度了一下,发现很多博客的内容都大致相同,不太方便使用。于是自己写了这么一个工具类,使用JDK中自带的ZipOutputStreamZipInoutStream实现对文件的压缩和解压。


█ 源码

  1. /**
  2. * 使用方法:
  3. * byte[] bytes = ZipUtil.createZipObject().addFile(fileBytes, "hello.xls").create();
  4. *
  5. * 需要添加多个文件就调用多次addFile,最后调用create生成字节数组即可
  6. *
  7. */
  8. public class ZipUtil {
  9. private ZipUtil() {
  10. throw new RuntimeException("Illegal operation");
  11. }
  12. // 压缩文件
  13. public static ZipObject createZipObject() {
  14. return new ZipObject();
  15. }
  16. // 解压文件,参数是压缩文件字节数组
  17. public static UnZipObject createUnZipObject(byte[] bytes) {
  18. if (bytes==null || bytes.length==0) {
  19. throw new IllegalArgumentException("bytes is null");
  20. }
  21. return new UnZipObject(bytes);
  22. }
  23. public static class ZipObject {
  24. // 工具流
  25. private ZipOutputStream zos;
  26. // 使用带有缓冲功能的文件流存储文件
  27. private ByteArrayOutputStream bos;
  28. private ZipObject() {
  29. bos = new ByteArrayOutputStream();
  30. // 文件数据流实际存储在了bos
  31. zos = new ZipOutputStream(bos);
  32. }
  33. /**
  34. * 添加一个文件到压缩包中
  35. * @param fileBytes 文件的字节数组
  36. * @param fileName 文件名,带文件类型的,比如:hello.xlsx
  37. * @return
  38. */
  39. public ZipObject addFile(byte[] fileBytes, String fileName) {
  40. try {
  41. // 可以理解一个ZipEntry就表示压缩包里面的一个文件
  42. ZipEntry zipEntry = new ZipEntry(fileName);
  43. zos.putNextEntry(zipEntry);
  44. zos.write(fileBytes, 0, fileBytes.length);
  45. } catch (IOException e) {
  46. if (bos!=null) {
  47. try {
  48. bos.close();
  49. } catch (IOException ee){}
  50. }
  51. if (zos!=null) {
  52. try {
  53. zos.close();
  54. } catch (IOException ee){}
  55. }
  56. }
  57. return this;
  58. }
  59. /**
  60. * 生成压缩包的字节数组
  61. * @return
  62. */
  63. public byte[] create() {
  64. byte[] bytes = null;
  65. try {
  66. // 将数据写到ByteArrayOutputStream中
  67. zos.finish();
  68. bytes = bos.toByteArray();
  69. bos.flush();
  70. zos.flush();
  71. } catch (IOException e) {
  72. e.printStackTrace();
  73. } finally {
  74. if (bos!=null) {
  75. try {
  76. bos.close();
  77. } catch (IOException e){}
  78. }
  79. if (zos!=null) {
  80. try {
  81. zos.close();
  82. } catch (IOException e){}
  83. }
  84. }
  85. return bytes;
  86. }
  87. }
  88. public static class UnZipObject {
  89. // 工具流
  90. private ZipInputStream zis;
  91. // 使用带有缓冲功能的文件流存储文件
  92. private ByteArrayInputStream bis;
  93. private int size;
  94. private UnZipObject(byte[] bytes) {
  95. size = bytes.length;
  96. bis = new ByteArrayInputStream(bytes);
  97. // 文件数据流实际存储在了bos
  98. zis = new ZipInputStream(bis);
  99. }
  100. /**
  101. * 获取压缩包里面的文件,一个ZipEntry表示一个文件
  102. * @return
  103. */
  104. public List<ZipEntry> getEntrys() {
  105. List<ZipEntry> list = new ArrayList<>();
  106. try {
  107. ZipEntry nextEntry = zis.getNextEntry();
  108. // 一个个循环读取压缩文件中的内容,放进bytes数组中
  109. while (nextEntry!=null) {
  110. byte[] bytes = new byte[size];
  111. zis.read(bytes);
  112. nextEntry.setExtra(bytes);
  113. list.add(nextEntry);
  114. nextEntry = zis.getNextEntry();
  115. }
  116. } catch (IOException e) {
  117. e.printStackTrace();
  118. if (bis!=null) {
  119. try {
  120. bis.close();
  121. } catch (IOException ee){}
  122. }
  123. if (zis!=null) {
  124. try {
  125. zis.close();
  126. } catch (IOException ee){}
  127. }
  128. }
  129. return list;
  130. }
  131. }
  132. }

█ 使用

压缩打包文件:

  1. public class ZipUtilTest {
  2. @Test
  3. public void testZipFile() {
  4. try {
  5. // 读取文件1
  6. File file1 = new File("E:\\project\\java\\src\\main\\resources\\zip\\zip1.text");
  7. FileInputStream fis1 = new FileInputStream(file1);
  8. byte[] fileBytes1 = new byte[fis1.available()];
  9. fis1.read(fileBytes1);
  10. // 读取文件2
  11. File file2 = new File("E:\\project\\java\\src\\main\\resources\\zip\\zip2.text");
  12. FileInputStream fis2 = new FileInputStream(file1);
  13. byte[] fileBytes2 = new byte[fis2.available()];
  14. fis2.read(fileBytes2);
  15. // 获取压缩包文件字节数组
  16. byte[] bytes = ZipUtil.createZipObject().addFile(fileBytes1, file1.getName()).addFile(fileBytes2, file2.getName()).create();
  17. /**
  18. * 如果是响应给浏览器的话,可以:
  19. * HttpServletResponse.getOutputStream().write(bytes[]);
  20. */
  21. // 将压缩包数据写到本地
  22. FileOutputStream fos = new FileOutputStream("E:\\project\\java\\src\\main\\resources\\zip\\hello.zip");
  23. fos.write(bytes);
  24. } catch (Exception e) {
  25. e.printStackTrace();
  26. }
  27. }
  28. }

解压压缩包中的文件:

  1. @Test
  2. public void testUnZipFile() {
  3. try {
  4. // 读取压缩文件
  5. File file = new File("E:\\project\\java\\src\\main\\resources\\zip\\hello.zip");
  6. FileInputStream fis1 = new FileInputStream(file);
  7. byte[] fileBytes1 = new byte[fis1.available()];
  8. fis1.read(fileBytes1);
  9. ZipUtil.UnZipObject unZipObject = ZipUtil.createUnZipObject(fileBytes1);
  10. List<ZipEntry> entryList = unZipObject.getEntrys();
  11. System.out.println("entryList:"+entryList.size());
  12. entryList.forEach(zipEntry -> {
  13. try {
  14. // zipEntry.getName() 压缩包里面的文件名
  15. FileOutputStream fos = new FileOutputStream("E:\\project\\"+zipEntry.getName());
  16. // zipEntry.getExtra()是压缩包里面的一个个文件数据
  17. fos.write(zipEntry.getExtra());
  18. fos.close();
  19. } catch (Exception e) {
  20. e.printStackTrace();
  21. }
  22. });
  23. } catch (Exception e) {
  24. e.printStackTrace();
  25. }
  26. }

发表评论

表情:
评论列表 (有 0 条评论,301人围观)

还没有评论,来说两句吧...

相关阅读