Java实现压缩解压文件 我会带着你远行 2022-12-11 09:14 173阅读 0赞 > **关键词:**ZipOutputStream** ** ZipInoutStream -------------------- 最近在工作中有需求需要在浏览器中一次性下载多个文件,于是想到了使用压缩的功能。百度了一下,发现很多博客的内容都大致相同,不太方便使用。于是自己写了这么一个工具类,使用JDK中自带的**ZipOutputStream**和**ZipInoutStream**实现对文件的压缩和解压。 -------------------- # **█ 源码** # /** * 使用方法: * byte[] bytes = ZipUtil.createZipObject().addFile(fileBytes, "hello.xls").create(); * * 需要添加多个文件就调用多次addFile,最后调用create生成字节数组即可 * */ public class ZipUtil { private ZipUtil() { throw new RuntimeException("Illegal operation"); } // 压缩文件 public static ZipObject createZipObject() { return new ZipObject(); } // 解压文件,参数是压缩文件字节数组 public static UnZipObject createUnZipObject(byte[] bytes) { if (bytes==null || bytes.length==0) { throw new IllegalArgumentException("bytes is null"); } return new UnZipObject(bytes); } public static class ZipObject { // 工具流 private ZipOutputStream zos; // 使用带有缓冲功能的文件流存储文件 private ByteArrayOutputStream bos; private ZipObject() { bos = new ByteArrayOutputStream(); // 文件数据流实际存储在了bos zos = new ZipOutputStream(bos); } /** * 添加一个文件到压缩包中 * @param fileBytes 文件的字节数组 * @param fileName 文件名,带文件类型的,比如:hello.xlsx * @return */ public ZipObject addFile(byte[] fileBytes, String fileName) { try { // 可以理解一个ZipEntry就表示压缩包里面的一个文件 ZipEntry zipEntry = new ZipEntry(fileName); zos.putNextEntry(zipEntry); zos.write(fileBytes, 0, fileBytes.length); } catch (IOException e) { if (bos!=null) { try { bos.close(); } catch (IOException ee){} } if (zos!=null) { try { zos.close(); } catch (IOException ee){} } } return this; } /** * 生成压缩包的字节数组 * @return */ public byte[] create() { byte[] bytes = null; try { // 将数据写到ByteArrayOutputStream中 zos.finish(); bytes = bos.toByteArray(); bos.flush(); zos.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (bos!=null) { try { bos.close(); } catch (IOException e){} } if (zos!=null) { try { zos.close(); } catch (IOException e){} } } return bytes; } } public static class UnZipObject { // 工具流 private ZipInputStream zis; // 使用带有缓冲功能的文件流存储文件 private ByteArrayInputStream bis; private int size; private UnZipObject(byte[] bytes) { size = bytes.length; bis = new ByteArrayInputStream(bytes); // 文件数据流实际存储在了bos zis = new ZipInputStream(bis); } /** * 获取压缩包里面的文件,一个ZipEntry表示一个文件 * @return */ public List<ZipEntry> getEntrys() { List<ZipEntry> list = new ArrayList<>(); try { ZipEntry nextEntry = zis.getNextEntry(); // 一个个循环读取压缩文件中的内容,放进bytes数组中 while (nextEntry!=null) { byte[] bytes = new byte[size]; zis.read(bytes); nextEntry.setExtra(bytes); list.add(nextEntry); nextEntry = zis.getNextEntry(); } } catch (IOException e) { e.printStackTrace(); if (bis!=null) { try { bis.close(); } catch (IOException ee){} } if (zis!=null) { try { zis.close(); } catch (IOException ee){} } } return list; } } } -------------------- # **█ 使用** # 压缩打包文件: public class ZipUtilTest { @Test public void testZipFile() { try { // 读取文件1 File file1 = new File("E:\\project\\java\\src\\main\\resources\\zip\\zip1.text"); FileInputStream fis1 = new FileInputStream(file1); byte[] fileBytes1 = new byte[fis1.available()]; fis1.read(fileBytes1); // 读取文件2 File file2 = new File("E:\\project\\java\\src\\main\\resources\\zip\\zip2.text"); FileInputStream fis2 = new FileInputStream(file1); byte[] fileBytes2 = new byte[fis2.available()]; fis2.read(fileBytes2); // 获取压缩包文件字节数组 byte[] bytes = ZipUtil.createZipObject().addFile(fileBytes1, file1.getName()).addFile(fileBytes2, file2.getName()).create(); /** * 如果是响应给浏览器的话,可以: * HttpServletResponse.getOutputStream().write(bytes[]); */ // 将压缩包数据写到本地 FileOutputStream fos = new FileOutputStream("E:\\project\\java\\src\\main\\resources\\zip\\hello.zip"); fos.write(bytes); } catch (Exception e) { e.printStackTrace(); } } } 解压压缩包中的文件: @Test public void testUnZipFile() { try { // 读取压缩文件 File file = new File("E:\\project\\java\\src\\main\\resources\\zip\\hello.zip"); FileInputStream fis1 = new FileInputStream(file); byte[] fileBytes1 = new byte[fis1.available()]; fis1.read(fileBytes1); ZipUtil.UnZipObject unZipObject = ZipUtil.createUnZipObject(fileBytes1); List<ZipEntry> entryList = unZipObject.getEntrys(); System.out.println("entryList:"+entryList.size()); entryList.forEach(zipEntry -> { try { // zipEntry.getName() 压缩包里面的文件名 FileOutputStream fos = new FileOutputStream("E:\\project\\"+zipEntry.getName()); // zipEntry.getExtra()是压缩包里面的一个个文件数据 fos.write(zipEntry.getExtra()); fos.close(); } catch (Exception e) { e.printStackTrace(); } }); } catch (Exception e) { e.printStackTrace(); } }
还没有评论,来说两句吧...