JAVA解压tar、zip、rar、gz、7z文件
1、添加pom依赖
<!-- tar解压依赖 --> <dependency > <groupId>org.apache.commons</groupId> <artifactId>commons-compress</artifactId> <version>1.20</version> </dependency> <!-- rar解压依赖 --> <dependency> <groupId>net.sf.sevenzipjbinding</groupId> <artifactId>sevenzipjbinding</artifactId> <version>16.02-2.01</version> </dependency> <dependency> <groupId>net.sf.sevenzipjbinding</groupId> <artifactId>sevenzipjbinding-all-platforms</artifactId> <version>16.02-2.01</version> </dependency> <!-- zip解压依赖 --> <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant</artifactId> <version>1.10.10</version> </dependency> <!-- 7z解压依赖 --> <dependency> <groupId>org.tukaani</groupId> <artifactId>xz</artifactId> <version>1.9</version> </dependency>
2、具体逻辑代码
/** * @description: 解压tar到指定的文件夹 * @date: 2023/11/13 14:34 * @param sourceFile 源文件绝对路径 * @param destDir 要解压到的目录地址 * @return boolean */ public static boolean unTar(String sourceFile, String destDir) { boolean flag = false; try (FileInputStream fis = new FileInputStream(sourceFile); BufferedInputStream bis = new BufferedInputStream(fis); TarArchiveInputStream tarInputStream = new TarArchiveInputStream(bis)) { TarArchiveEntry tarEntry; while ((tarEntry = tarInputStream.getNextTarEntry()) != null) { File outputFile = new File(destDir, tarEntry.getName()); if (tarEntry.isDirectory()) { outputFile.mkdirs(); } else { outputFile.getParentFile().mkdirs(); try (OutputStream outputStream = new FileOutputStream(outputFile)) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = tarInputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } } } } flag = true; } catch (IOException e) { log.info("解压tar文件失败:{}, {}", sourceFile, e.toString()); } return flag; } /** * @description: 解压tar.gz到指定的文件夹 * @date: 2023/5/29 17:56 * @param sourceFile 源文件绝对路径 * @param destDir 要解压到的目录地址 * @return boolean */ public static boolean unTarGz(String sourceFile, String destDir) { Path source = Paths.get(sourceFile); Path target = Paths.get(destDir); boolean flag = false; try (InputStream fi = Files.newInputStream(source); BufferedInputStream bi = new BufferedInputStream(fi); GzipCompressorInputStream gzi = new GzipCompressorInputStream(bi); TarArchiveInputStream ti = new TarArchiveInputStream(gzi)) { ArchiveEntry entry; while ((entry = ti.getNextEntry()) != null) { String entryName = entry.getName(); Path targetDirResolved = target.resolve(entryName); Path newDestPath = targetDirResolved.normalize(); if (entry.isDirectory()) { newDestPath = Paths.get(destDir + "/" + entryName); Files.createDirectories(newDestPath); } else { Files.copy(ti, newDestPath, StandardCopyOption.REPLACE_EXISTING); } } flag = true; } catch (Exception e) { log.info("解压tar.gz文件失败:{},{}", sourceFile, e); } return flag; } /** * @description: 解压zip到指定的文件夹 * @date: 2023/5/29 17:56 * @param sourceFile 源文件绝对路径 * @param destDir 要解压到的目录地址 * @return boolean */ public static boolean unZip(String srcPath, String destDirPath) { boolean flag = false; File srcFile = new File(srcPath); if (!srcFile.exists()) { throw new RuntimeException(srcFile.getPath() + "所指文件不存在"); } // 开始解压 ZipFile zipFile = null; try { zipFile = new ZipFile(srcFile); // zipFile = new ZipFile(srcFile, Charset.forName("GBK")); //含有中文 使用java.util.zip才需要指定这个,后面即使指定了也还是有问题,所以放弃这个改成Ant.jar Enumeration <? > entries = zipFile.getEntries(); while (entries.hasMoreElements()) { ZipEntry entry = (ZipEntry) entries.nextElement(); System.out.println("解压" + entry.getName()); // 如果是文件夹,就创建个文件夹 if (entry.isDirectory()) { String dirPath = destDirPath + "/" + entry.getName(); File dir = new File(dirPath); dir.mkdirs(); } else { // 如果是文件,就先创建一个文件,然后用io流把内容copy过去 File targetFile = new File(destDirPath + "/" + entry.getName()); // 保证这个文件的父文件夹必须要存在 if (!targetFile.getParentFile().exists()) { targetFile.getParentFile().mkdirs(); } targetFile.createNewFile(); // 将压缩文件内容写入到这个文件中 InputStream is = zipFile.getInputStream(entry); FileOutputStream fos = new FileOutputStream(targetFile); int len; byte[] buf = new byte[2048]; while ((len = is.read(buf)) != -1) { fos.write(buf, 0, len); } // 关流顺序,先打开的后关闭 fos.close(); is.close(); } } flag = true; } catch (Exception e) { log.error("解析压缩包文件异常:{}", srcPath); throw new RuntimeException("unzip error from ZipUtils", e); } finally { if (zipFile != null) { try { zipFile.close(); } catch (IOException e) { e.printStackTrace(); } } } return flag; } /** * @description: 解压7z到指定的文件夹 * @date: 2023/5/29 18:13 * @param filePath 源文件绝对路径 * @param destDir 要解压到的目录地址 * @return boolean */ public static boolean un7z(String filePath, String descDir){ boolean flag = false; SevenZFile zIn = null; try { File file = new File(filePath); zIn = new SevenZFile(file); SevenZArchiveEntry entry = null; while ((entry = zIn.getNextEntry()) != null){ if(!entry.isDirectory()){ File newFile = new File(descDir, entry.getName()); if(!newFile.exists()){ new File(newFile.getParent()).mkdirs(); } OutputStream out = new FileOutputStream(newFile); BufferedOutputStream bos = new BufferedOutputStream(out); int len = -1; byte[] buf = new byte[(int)entry.getSize()]; while ((len = zIn.read(buf)) != -1){ bos.write(buf, 0, len); } bos.flush(); bos.close(); out.close(); } } flag = true; } catch (Exception e) { log.info("解压7z出错 {}, {}", filePath,e.getMessage()); }finally { try { if (zIn != null) zIn.close(); } catch (IOException e) { log.info("解压7z后关闭文件流程失败 {}, {}", filePath,e.getMessage()); } } return flag; } /** * @description: 解压gzip到指定的文件夹 注意解压出来的直接是一个文件 * @date: 2023/8/23 15:16 * @param sourceFile 源文件绝对路径 * @param targetFolder 要解压到的目录地址 * @return boolean */ public static boolean unGzip(String sourceFile,String targetFolder){ boolean flag = false; try { FileInputStream fin = new FileInputStream(sourceFile); //建立gzip解压工作流 GZIPInputStream gzin = new GZIPInputStream(fin); //建立解压文件输出流 File file = new File(sourceFile); String fileName = file.getName(); targetFolder = targetFolder + "/" + fileName.substring(0, fileName.lastIndexOf('.')); FileOutputStream fout = new FileOutputStream(targetFolder); int num; byte[] buf=new byte[1024]; while ((num = gzin.read(buf,0,buf.length)) != -1) { fout.write(buf,0,num); } gzin.close(); fout.close(); fin.close(); flag = true; } catch (IOException e) { log.info("解压gz文件失败:{}, {}",sourceFile,e.getMessage()); } return flag; } /** * @description: 解压rar到指定的文件夹 * @date: 2023/5/29 17:56 * @param sourceFile 源文件绝对路径 * @param destDir 要解压到的目录地址 * @return boolean */ public static boolean unRar(String rarPath, String descDir) { if (!descDir.endsWith("/")) { descDir = descDir + "/"; } File pathFile = new File(descDir); if (!pathFile.exists()) { pathFile.mkdirs(); } File rarFile = new File(rarPath); try { RandomAccessFile randomAccessFile = new RandomAccessFile(rarFile.toString(), "r"); IInArchive archive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile)); int[] in = new int[archive.getNumberOfItems()]; for (int i = 0; i < in .length; i++) { in [i] = i; } archive.extract( in , false, new ExtractCallback(archive, pathFile.getAbsolutePath() + "/")); archive.close(); randomAccessFile.close(); return true; } catch (Exception e) { log.error("解压rar出错 {}", e.getMessage()); return false; } } /** * @description: 解压rar辅助类 */ public class ExtractCallback implements IArchiveExtractCallback { private Logger log = LoggerFactory.getLogger(ExtractCallback.class); private int index; private IInArchive inArchive; private String ourDir; public ExtractCallback(IInArchive inArchive, String ourDir) { this.inArchive = inArchive; this.ourDir = ourDir; } @ Override public void setCompleted(long arg0) throws SevenZipException {} @ Override public void setTotal(long arg0) throws SevenZipException {} @ Override public ISequentialOutStream getStream(int index, ExtractAskMode extractAskMode) throws SevenZipException { this.index = index; String path = (String) inArchive.getProperty(index, PropID.PATH); final boolean isFolder = (boolean) inArchive.getProperty(index, PropID.IS_FOLDER); String finalPath = path; File newfile = null; try { String fileEnd = ""; //对文件名,文件夹特殊处理 if (finalPath.contains(File.separator)) { fileEnd = finalPath.substring(finalPath.lastIndexOf(File.separator) + 1); } else { fileEnd = finalPath; } finalPath = finalPath.substring(0, finalPath.lastIndexOf(File.separator) + 1) + fileEnd; //目录层级 finalPath = finalPath.replaceAll("\\\\", "/"); String suffixName = ""; int suffixIndex = fileEnd.lastIndexOf("."); if (suffixIndex != -1) { suffixName = fileEnd.substring(suffixIndex + 1); } newfile = createFile(isFolder, ourDir + finalPath); final boolean directory = (boolean) inArchive.getProperty(index, PropID.IS_FOLDER); } catch (Exception e) { log.error("rar解压失败{}", e.getMessage()); } File finalFile = newfile; return data - > { save2File(finalFile, data); return data.length; }; } @ Override public void prepareOperation(ExtractAskMode arg0) throws SevenZipException {} @ Override public void setOperationResult(ExtractOperationResult extractOperationResult) throws SevenZipException {} public File createFile(boolean isFolder, String path) { //前置是因为空文件时不会创建文件和文件夹 File file = new File(path); try { if (!isFolder) { File parent = file.getParentFile(); if ((!parent.exists())) { parent.mkdirs(); } if (!file.exists()) { file.createNewFile(); } } else { if ((!file.exists())) { file.mkdirs(); } } } catch (Exception e) { log.error("rar创建文件或文件夹失败 {}", e.getMessage()); } return file; } public boolean save2File(File file, byte[] msg) { OutputStream fos = null; try { fos = new FileOutputStream(file, true); fos.write(msg); fos.flush(); return true; } catch (FileNotFoundException e) { log.error("rar保存文件失败{}", e.getMessage()); return false; } catch (IOException e) { log.error("rar保存文件失败{}", e.getMessage()); return false; } finally { try { fos.close(); } catch (IOException e) { log.error("rar保存文件失败{}", e.getMessage()); } } } }