ZIP文件操作工具类
2 3 import lombok.extern.slf4j.Slf4j; 4 import org.apache.commons.io.FilenameUtils; 5 6 import java.io.*; 7 import java.nio.charset.Charset; 8 import java.util.zip.ZipEntry; 9 import java.util.zip.ZipInputStream; 10 import java.util.zip.ZipOutputStream; 11 12 13 @Slf4j 14 public class PfZipUtil { 15 public static final int BUFFER_SIZE = 2048; 16 17 private PfZipUtil() { 18 } 19 20 public static void zipFile(String toZipFilePath, String zipFilePath) throws IOException { 21 InputStream inputStream = null; 22 ZipOutputStream zipOutputStream = null; 23 File toZipFile = new File(toZipFilePath); 24 File zipFile = new File(zipFilePath); 25 try { 26 inputStream = new FileInputStream(toZipFile); 27 zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFile)); 28 zipOutputStream.putNextEntry(new ZipEntry(toZipFile.getName())); 29 int currentByte = -1; 30 log.debug(String.valueOf(currentByte)); 31 byte[] data = new byte[BUFFER_SIZE]; 32 while ((currentByte = inputStream.read(data, 0, BUFFER_SIZE)) != -1) { 33 zipOutputStream.write(data, 0, currentByte); 34 } 35 zipOutputStream.flush(); 36 } finally { 37 SafeCloseUtil.safeClose(inputStream); 38 SafeCloseUtil.safeClose(zipOutputStream); 39 if (toZipFile.exists()) { 40 boolean isDeleted = toZipFile.delete(); 41 if (!isDeleted) { 42 log.warn("delete file failed " + toZipFile.getAbsolutePath()); 43 } 44 } 45 } 46 } 47 48 public static void zipFiles(File[] toZipFilePath, String zipFilePath) throws IOException { 49 InputStream inputStream = null; 50 zipFilePath = PfStringUtil.getLegalPath(zipFilePath); 51 File zipFile = new File(zipFilePath); 52 FileOutputStream outputStream = new FileOutputStream(zipFile); 53 ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream); 54 try { 55 for (File file : toZipFilePath) { 56 inputStream = new FileInputStream(file.getAbsolutePath()); 57 zipOutputStream.putNextEntry(new ZipEntry(file.getName())); 58 int currentByte = -1; 59 log.debug(String.valueOf(currentByte)); 60 byte[] data = new byte[BUFFER_SIZE]; 61 while ((currentByte = inputStream.read(data, 0, BUFFER_SIZE)) != -1) { 62 zipOutputStream.write(data, 0, currentByte); 63 } 64 zipOutputStream.closeEntry(); 65 inputStream.close(); 66 } 67 zipOutputStream.close(); 68 } finally { 69 SafeCloseUtil.safeClose(inputStream); 70 SafeCloseUtil.safeClose(zipOutputStream); 71 for (File file : toZipFilePath) { 72 if (file.exists()) { 73 boolean isDeleted = file.delete(); 74 if (!isDeleted) { 75 log.warn("delete file failed " + file.getAbsolutePath()); 76 } 77 } 78 } 79 } 80 } 81 82 public static void createZip(String sourcePath, String zipPathNo) { 83 String zipPath = FileUtil.verifyNonNullString(zipPathNo); 84 if (zipPath == null) { 85 return; 86 } 87 FileOutputStream fos = null; 88 ZipOutputStream zos = null; 89 try { 90 fos = new FileOutputStream(zipPath); 91 zos = new ZipOutputStream(fos); 92 String sourcePath2 = FileUtil.verifyNonNullString(sourcePath); 93 if (sourcePath2 != null) { 94 writeZip(new File(sourcePath2), "", zos); 95 } 96 } catch (FileNotFoundException e) { 97 log.error("creat zipfile error", e); 98 } finally { 99 try { 100 if (zos != null) { 101 zos.close(); 102 } 103 if (fos != null) { 104 fos.close(); 105 } 106 } catch (IOException e) { 107 log.error("creat zipfile error", e); 108 } 109 110 } 111 } 112 113 private static void writeZip(File file, String parentPath, ZipOutputStream zos) { 114 if (file.exists()) { 115 if (file.isDirectory()) {// 处理文件夹 116 parentPath += file.getName() + File.separator; 117 File[] files = file.listFiles(); 118 if (files != null && files.length != 0) { 119 for (File f : files) { 120 writeZip(f, parentPath, zos); 121 } 122 } else { // 空目录则创建当前目录 123 try { 124 zos.putNextEntry(new ZipEntry(parentPath)); 125 } catch (IOException e) { 126 e.printStackTrace(); 127 } 128 } 129 } else { 130 FileInputStream fis = null; 131 try { 132 fis = new FileInputStream(file); 133 ZipEntry ze = new ZipEntry(parentPath + file.getName()); 134 zos.putNextEntry(ze); 135 byte[] content = new byte[1024]; 136 int len = -1; 137 log.debug(String.valueOf(len)); 138 while ((len = fis.read(content)) != -1) { 139 zos.write(content, 0, len); 140 zos.flush(); 141 } 142 143 } catch (FileNotFoundException e) { 144 log.error("creat zipfile error", e); 145 } catch (IOException e) { 146 log.error("creat zipfile error", e); 147 } finally { 148 try { 149 if (fis != null) { 150 fis.close(); 151 } 152 } catch (IOException e) { 153 log.error("creat zipfile error", e); 154 } 155 } 156 } 157 } 158 } 159 160 private static void createDirIfNotExists(String destPath, String entryName) { 161 String destPath2 = FileUtil.verifyNonNullString(destPath + File.separator + entryName); 162 if (destPath2 != null) { 163 File file = new File(destPath2); 164 if (!file.exists()) { 165 boolean success = file.mkdirs(); 166 if (!success) { 167 log.info("mkdir error,path:" + file); 168 } 169 } 170 } 171 } 172 173 /** 174 * @param zipFileName 175 * @param destPath 176 * @return 解压文件的根目录 177 */ 178 public static File unZip(String zipFileName, String destPath) { 179 180 zipFileName = FileUtil.verifyNonNullString(zipFileName); 181 destPath = FileUtil.verifyNonNullString(destPath); 182 if (zipFileName == null || zipFileName.length() <= 0) { 183 log.warn("zipFileName is empty!"); 184 return null; 185 } 186 if (destPath == null || destPath.length() <= 0) { 187 log.warn("destPath is empty!"); 188 return null; 189 } 190 191 FileInputStream fin = null; 192 ZipInputStream in = null; 193 FileOutputStream os = null; 194 try { 195 String zipFileName1 = FileUtil.verifyNonNullString(zipFileName); 196 fin = new FileInputStream(zipFileName1); 197 in = new ZipInputStream(fin); 198 // ZIP 文件条目 199 ZipEntry entry; 200 201 while ((entry = in.getNextEntry()) != null) { 202 String entryName = entry.getName(); 203 // 判断是否为目录条目,目录条目定义为其名称以 '/' 204 // 结尾的条目。 205 entryName = FilenameUtils.normalize(entryName); 206 if (entry.isDirectory()) { 207 createDirIfNotExists(destPath, entryName); 208 } else { 209 // 如果压缩包存在路径conf/explain.xml,存在conf文件夹,但java读取不到conf文件夹,而是直接读取其中的文件。我们要先判断conf文件夹是否已经 210 // 创建,如果没有必须先建立conf,否则解压失败 211 String path = destPath + File.separator + entryName; 212 /** 213 * 下面两行代码是为了屏蔽掉路径中的"/",统一为"\", 214 */ 215 String path2 = FileUtil.verifyNonNullString(path); 216 if (path2 != null) { 217 File file = new File(path2); 218 String tempPath = file.getPath(); 219 220 tempPath = tempPath.substring(0, tempPath.lastIndexOf(File.separator)); 221 String tempPath2 = FileUtil.verifyNonNullString(tempPath); 222 if (tempPath2 != null) { 223 File tempFile = new File(tempPath2); 224 if (!tempFile.exists()) { 225 boolean success = tempFile.mkdirs(); 226 if (!success) { 227 log.info("mkdir error,path:"); 228 } 229 } 230 } 231 } 232 String destPath2 = FileUtil.verifyNonNullString(destPath + File.separator + entryName); 233 if (destPath2 != null) { 234 os = new FileOutputStream(destPath2); 235 // Transfer bytes from the ZIP 236 // file to the output file 237 byte[] buf = new byte[1024]; 238 int len = 0; 239 log.debug(String.valueOf(len)); 240 while ((len = in.read(buf)) > 0) { 241 os.write(buf, 0, len); 242 } 243 os.close(); 244 in.closeEntry(); 245 } 246 //fin.close(); 247 } 248 } 249 return new File(destPath); 250 } catch (IOException e) { 251 log.error(e.getMessage(), e); 252 } finally { 253 closeFileResource(fin, in, os); 254 } 255 return null; 256 } 257 258 /** 259 * 计算ZIP文件的解压大小 260 * 261 * @param inputStream 输入流 262 * 注:输入流由调用方负责关闭 263 * @return 解压大小 264 */ 265 public static long getUncompressedSize(InputStream inputStream) throws IOException { 266 ZipInputStream zipInputStream = new ZipInputStream(inputStream, Charset.forName("GBK")); 267 byte[] buffer = new byte[8 * 1024 * 1024]; 268 long uncompressedSize = 0; 269 ZipEntry zipEntry; 270 while ((zipEntry = zipInputStream.getNextEntry()) != null) { 271 long size = zipEntry.getSize(); 272 // ZipEntry的size可能为-1,表示未知 273 if (size == -1) { 274 int len; 275 while ((len = zipInputStream.read(buffer, 0, buffer.length)) != -1) { 276 uncompressedSize += len; 277 } 278 } else { 279 uncompressedSize += size; 280 } 281 zipInputStream.closeEntry(); 282 } 283 return uncompressedSize; 284 } 285 286 private static void closeFileResource(FileInputStream fin, ZipInputStream in, FileOutputStream os) { 287 if (fin != null) { 288 try { 289 fin.close(); 290 } catch (IOException e) { 291 log.error(e.getMessage(), e); 292 } 293 294 } 295 if (in != null) { 296 try { 297 in.close(); 298 } catch (IOException e) { 299 log.error(e.getMessage(), e); 300 } 301 302 } 303 if (os != null) { 304 try { 305 os.close(); 306 } catch (IOException e) { 307 log.error(e.getMessage(), e); 308 } 309 310 } 311 } 312 313 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix