一、引入依賴
<dependency><groupId>net.lingala.zip4j</groupId><artifactId>zip4j</artifactId><version>1.3.1</version></dependency>
二、使用添加文件(addFiles)的方式生成壓縮包
/*** @Author wangtw* @Description 使用addFiles方式壓縮文件* @Date 07:34 2023/11/22* @param fileList 需要壓縮的文件列表* @param zipPath zip包路徑* @param password zip包密碼* @return**/public static void zip(ArrayList<File> fileList, String zipPath, String password) {ZipParameters parameters = new ZipParameters();// 壓縮方式parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);// 壓縮級別parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);if (StringUtils.hasText(password)) {parameters.setEncryptFiles(true);// 加密方式parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);parameters.setPassword(password.toCharArray());}try {ZipFile zipFile = new ZipFile(zipPath);zipFile.addFiles(fileList, parameters);} catch (ZipException e) {e.printStackTrace();}}
三、使用添加流(addStream)的方式生成壓縮文件
/*** @Author wangtw* @Description 使用addStream方式壓縮文件* @Date 20:01 2023/11/22* @param fileList 文件列比啊* @param zipPath zip包路徑* @param password 密碼* @return**/public static void zipByInputStream(ArrayList<File> fileList, String zipPath, String password) throws ZipException, FileNotFoundException {ZipFile zipFile = new ZipFile(zipPath);for (File file : fileList) {InputStream inputStream = new FileInputStream(file);ZipParameters parameters = new ZipParameters();// 壓縮方式parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);// 壓縮級別parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);if (StringUtils.hasText(password)) {parameters.setEncryptFiles(true);// 加密方式parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);parameters.setPassword(password.toCharArray());}parameters.setSourceExternalStream(true);parameters.setFileNameInZip(file.getName());zipFile.addStream(inputStream, parameters);// 關閉輸入流IOUtils.closeQuietly(inputStream);}}
四、向壓縮包輸出流(ZipOutputStream)中寫入文件
1、示例代碼
/*** 壓縮文件到輸出流中* @param fileList 文件列表* @param outputStream 壓縮包輸出流* @param password 壓縮包密碼* @throws IOException* @throws ZipException*/public static void zipOutputStream(ArrayList<File> fileList, OutputStream outputStream, String password) throws IOException, ZipException {ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);for (File file : fileList) {ZipParameters parameters = new ZipParameters();// 壓縮方式parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);// 壓縮級別parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);if (StringUtils.hasText(password)) {parameters.setEncryptFiles(true);// 加密方式parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);parameters.setPassword(password.toCharArray());}parameters.setSourceExternalStream(true);parameters.setFileNameInZip(file.getName());zipOutputStream.putNextEntry(null, parameters);InputStream inputStream = new FileInputStream(file);byte[] bytes=new byte[1024 * 1024];int len;while((len = inputStream.read(bytes)) != -1){zipOutputStream.write(bytes,0, len);}IOUtils.closeQuietly(inputStream);zipOutputStream.closeEntry();}zipOutputStream.finish();}
2、測試代碼
@Testpublic void zipOutputStreamTest() {File fileone = new File("/Users/outenmon/workspace/idea_workspace/java/cento-practice/src/main/resources/io-test/test.txt");File filetwo = new File("/Users/outenmon/workspace/idea_workspace/java/cento-practice/src/main/resources/application.yaml");ArrayList<File> fileList = new ArrayList<>();fileList.add(fileone);fileList.add(filetwo);OutputStream outputStream = null;try {outputStream = new FileOutputStream(new File(new Date().getTime() + ".zip"));zipOutputStream(fileList, outputStream, "123456");} catch (FileNotFoundException e) {e.printStackTrace();} catch (ZipException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {IOUtils.closeQuietly(outputStream);}}
五、異常總結
1、net.lingala.zip4j.exception.ZipException: input file is null
需要把ZipParameters對象的isSourceExternalStream屬性設置為true,例如:parameters.setSourceExternalStream(true);
2、net.lingala.zip4j.exception.ZipException: file name is empty for external stream
需要設置ZipParameters對象的fileNameInZip屬性,例如:parameters.setFileNameInZip(file.getName());
代碼地址:
https://gitee.com/wangtianwen1996/cento-practice/blob/master/src/test/java/com/xiaobai/Zip4jTest.java