java将文件压缩成zip_java常用jar包下载

(21) 2024-09-05 08:01:01

最近由于客户来回修改需求,使得我对代码也是反复修改,最终折腾完毕后,让我总结了3种Java生成的zip包。

1.普通zip包,解压后的样子与打包压缩前一模一样,直接解压即可。

过程如下:

打包E盘下packs文件夹中的内容,生成的zip包输出到E盘下,名称为packs.zip

具体代码实现过程注释即可。

import java.nio.file.Paths; //compress方法需要传入2个参数,是两个地址 //第一个地址是目标打包文件的地址,第二个是zip包输出的地址 public static void main(String[] args) throws IOException { String hallFilePath = "E:/" + "packs"; compress(Paths.get(hallFilePath).toString(), hallFilePath + ".zip"); } //由此开始是所有相关的工具方法 public static void compress(String fromPath, String toPath) throws IOException { File fromFile = new File(fromPath); File toFile = new File(toPath); if (!fromFile.exists()) { throw new ServiceException(fromPath + "不存在!"); } try (FileOutputStream outputStream = new FileOutputStream(toFile); CheckedOutputStream checkedOutputStream = new CheckedOutputStream(outputStream, new CRC32()); ZipOutputStream zipOutputStream = new ZipOutputStream(checkedOutputStream)) { String baseDir = ""; compress(fromFile, zipOutputStream, baseDir); } } private static void compress(File file, ZipOutputStream zipOut, String baseDir) throws IOException { if (file.isDirectory()) { compressDirectory(file, zipOut, baseDir); } else { compressFile(file, zipOut, baseDir); } } private static void compressFile(File file, ZipOutputStream zipOut, String baseDir) throws IOException { if (!file.exists()) { return; } try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) { ZipEntry entry = new ZipEntry(baseDir + file.getName()); zipOut.putNextEntry(entry); int count; byte[] data = new byte[BUFFER]; while ((count = bis.read(data, 0, BUFFER)) != -1) { zipOut.write(data, 0, count); } } } private static void compressDirectory(File dir, ZipOutputStream zipOut, String baseDir) throws IOException { File[] files = dir.listFiles(); if (files != null && ArrayUtils.isNotEmpty(files)) { for (File file : files) { compress(file, zipOut, baseDir + dir.getName() + File.separator); } } }

压缩前的目标文件如下:

java将文件压缩成zip_java常用jar包下载 (https://mushiming.com/)  第1张

 压缩后输出的文件以及解压后:

java将文件压缩成zip_java常用jar包下载 (https://mushiming.com/)  第2张java将文件压缩成zip_java常用jar包下载 (https://mushiming.com/)  第3张

2.压缩后的压缩包解压即是文件,不需要文件夹,就是上面的案例,解压后还有一个packs文件夹,这里跳过,解压出来就是文件列表:

大体步骤相似,打包时代码需要调整,先上全部的代码:

public static void main(String[] args) throws IOException { String hallFilePath = "E:/" + "packs"; compress(Paths.get(hallFilePath).toString(), hallFilePath + ".zip"); } public static void compress(String fromPath, String toPath) throws IOException { File fromFile = new File(fromPath); File toFile = new File(toPath); if (!fromFile.exists()) { throw new ServiceException(fromPath + "不存在!"); } try (FileOutputStream outputStream = new FileOutputStream(toFile); CheckedOutputStream checkedOutputStream = new CheckedOutputStream(outputStream, new CRC32()); ZipOutputStream zipOutputStream = new ZipOutputStream(checkedOutputStream)) { String baseDir = ""; compress(fromFile, zipOutputStream, baseDir); } } private static void compress(File file, ZipOutputStream zipOut, String baseDir) throws IOException { if (file.isDirectory()) { compressDirectory(file, zipOut, baseDir); } else { if (baseDir.equals("packs" + File.separator)) { baseDir = File.separator; } else if (baseDir.equals("packs" + File.separator + "examineeInfo" + File.separator)) { baseDir = "examineeInfo" + File.separator; } compressFile(file, zipOut, baseDir); } } private static void compressFile(File file, ZipOutputStream zipOut, String baseDir) throws IOException { if (!file.exists()) { return; } try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) { ZipEntry entry = new ZipEntry(baseDir + file.getName()); zipOut.putNextEntry(entry); int count; byte[] data = new byte[BUFFER]; while ((count = bis.read(data, 0, BUFFER)) != -1) { zipOut.write(data, 0, count); } } } private static void compressDirectory(File dir, ZipOutputStream zipOut, String baseDir) throws IOException { File[] files = dir.listFiles(); if (files != null && ArrayUtils.isNotEmpty(files)) { for (File file : files) { compress(file, zipOut, baseDir + dir.getName() + File.separator); } } }

这里主要是有第二个compress方法来处理:

由于文件夹结构如下:

java将文件压缩成zip_java常用jar包下载 (https://mushiming.com/)  第4张

 这个方法在打包时,将外层的文件夹去掉,只保留内部文件夹

private static void compress(File file, ZipOutputStream zipOut, String baseDir) throws IOException {         if (file.isDirectory()) {             compressDirectory(file, zipOut, baseDir);         } else { //如果是文件夹,进来判断,是最外层packs文件夹还是内部的examineeInfo文件夹 //是最外层的则忽略掉,是内部的则把外层文件夹名称去掉             if (baseDir.equals("packs" + File.separator)) {                 baseDir = File.separator;             } else if (baseDir.equals("packs" + File.separator + "examineeInfo" + File.separator)) {                 baseDir = "examineeInfo" + File.separator;             }             compressFile(file, zipOut, baseDir);         }     }

这样压缩后的zip包解压后,直接出现文件,没有最外层文件夹:

java将文件压缩成zip_java常用jar包下载 (https://mushiming.com/)  第5张

3.压缩时给zip包添加密码:

打出一个带解压密码的zip包:

程序运行示例截图: 

java将文件压缩成zip_java常用jar包下载 (https://mushiming.com/)  第6张

示例代码:

public static void main(String[] args) { //随机密码生成工具 String ownerPassword = PdfEncryptUtil.getCharAndNum(20); //打包目标文件夹 String hallFilePath = "E:" + File.separator+ "packs"; //压缩包输出文件夹 String outPath = "E:" +File.separator+ "examineeInfo.zip"; //调用压缩方法zip进行压缩,参数含义下面介绍,返回的是压缩包的输出路径 String zipPath = zip(hallFilePath, outPath, false, "ceshi"); //打印出来 System.out.println(zipPath); }

zip方法工具中的方法:

/** * 使用给定密码压缩指定文件或文件夹到指定位置. * <p> * dest可传最终压缩文件存放的绝对路径,也可以传存放目录,也可以传null或者"" * 如果传null或者""则将压缩文件存放在当前目录,即跟源文件同目录,压缩文件名取源文件名,以.zip为后缀; * 如果以路径分隔符(File.separator)结尾,则视为目录,压缩文件名取源文件名,以.zip为后缀,否则视为文件名. * * @param src 要压缩的文件或文件夹路径 * @param dest 压缩文件存放路径 * @param isCreateDir 是否在压缩文件里创建目录,仅在压缩文件为目录时有效. * 如果为false,将直接压缩目录下文件到压缩文件. * @param passwd 压缩使用的密码 * @return 最终的压缩文件存放的绝对路径, 如果为null则说明压缩失败. */ public static String zip(String src, String dest, boolean isCreateDir, String passwd) { File srcFile = new File(src); dest = buildDestinationZipFilePath(srcFile, dest); ZipParameters parameters = new ZipParameters(); // 压缩方式 parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); // 压缩级别 parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); if (!StringUtils.isEmpty(passwd)) { parameters.setEncryptFiles(true); // 加密方式 parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD); parameters.setPassword(passwd.toCharArray()); } try { ZipFile zipFile = new ZipFile(dest); if (srcFile.isDirectory()) { // 如果不创建目录的话,将直接把给定目录下的文件压缩到压缩文件,即没有目录结构 if (!isCreateDir) { File[] subFiles = srcFile.listFiles(); for (int i = 0; i < subFiles.length; i++) { if (subFiles[i].isDirectory()) { zipFile.addFolder(subFiles[i], parameters); } else { ArrayList<File> temp = new ArrayList<File>(); Collections.addAll(temp, subFiles[i]); zipFile.addFiles(temp, parameters); } } return dest; } zipFile.addFolder(srcFile, parameters); } else { zipFile.addFile(srcFile, parameters); } return dest; } catch (ZipException e) { e.printStackTrace(); } return null; } private static String buildDestinationZipFilePath(File srcFile, String destParam) { if (StringUtils.isEmpty(destParam)) { if (srcFile.isDirectory()) { destParam = srcFile.getParent() + File.separator + srcFile.getName() + ".zip"; } else { String fileName = srcFile.getName().substring(0, srcFile.getName().lastIndexOf(".")); destParam = srcFile.getParent() + File.separator + fileName + ".zip"; } } else { // 在指定路径不存在的情况下将其创建出来 createDestDirectoryIfNecessary(destParam); if (destParam.endsWith(File.separator)) { String fileName = ""; if (srcFile.isDirectory()) { fileName = srcFile.getName(); } else { fileName = srcFile.getName().substring(0, srcFile.getName().lastIndexOf(".")); } destParam += fileName + ".zip"; } } return destParam; } private static void createDestDirectoryIfNecessary(String destParam) { File destDir = null; if (destParam.endsWith(File.separator)) { destDir = new File(destParam); } else { destDir = new File(destParam.substring(0, destParam.lastIndexOf(File.separator))); } if (!destDir.exists()) { destDir.mkdirs(); } }

这里打包出来的加密zip包也是解压开就是文件列表的格式,没有最外层文件夹包裹,如果想要最外层文件夹包裹,只需要改动下zip方法的try块中的if...else语句即可:

try { ZipFile zipFile = new ZipFile(dest); if (srcFile.isDirectory()) { // 如果不创建目录的话,将直接把给定目录下的文件压缩到压缩文件,即没有目录结构 if (!isCreateDir) { File[] subFiles = srcFile.listFiles(); ArrayList<File> temp = new ArrayList<File>(); Collections.addAll(temp, subFiles); zipFile.addFiles(temp, parameters); return dest; } zipFile.addFolder(srcFile, parameters); } else { zipFile.addFile(srcFile, parameters); } return dest; } catch (ZipException e) { e.printStackTrace(); }

生成效果:

java将文件压缩成zip_java常用jar包下载 (https://mushiming.com/)  第7张

java将文件压缩成zip_java常用jar包下载 (https://mushiming.com/)  第8张

注意:

1.zip包输出地址在定义时,一定要以.zip结尾,否则会出错。

2.代表文件夹层级关系的/在有的方法中,或者linux服务器上不识别,最好使用File.separator来表示层级,上面我也有用到过。

3.密码最好使用动态生成的密码,来提高安全性。

压缩的方法很多,工作之余匆匆记录,肯定有不是很合理很全面的地方,有大佬看到欢迎指点。

THE END

发表回复