Java解压rar文件的两种实现方法
作者:香蕉加奶茶
这篇文章主要介绍了Java解压rar文件的两种实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
Java解压rar文件的两种方法
方法一
private static void extractRar(String rarPath, String destDir) throws IOException, RarException { File dstDiretory = new File(destDir); if (!dstDiretory.exists()) { dstDiretory.mkdirs(); } File rarFile = new File(rarPath); Archive archive = new Archive(new FileInputStream(rarFile)); List<FileHeader> fileHeaders = archive.getFileHeaders(); for (FileHeader fileHeader : fileHeaders) { if (fileHeader.isDirectory()) { String fileName = fileHeader.getFileNameW(); if (!existZH(fileName)) { fileName = fileHeader.getFileNameString(); } File dir = new File(destDir + File.separator + fileName); if (!dir.exists()) { dir.mkdirs(); } } else { String fileName = fileHeader.getFileNameW().trim(); if (!existZH(fileName)) { fileName = fileHeader.getFileNameString().trim(); } File file = new File(destDir + File.separator + fileName); try { if (!file.exists()) { if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } file.createNewFile(); } FileOutputStream os = new FileOutputStream(file); archive.extractFile(fileHeader, os); os.close(); } catch (Exception ex) { throw ex; } } } archive.close(); } //判断文件名有没有正则表达式 public static boolean existZH(String str) { String regEx = "[\\u4e00-\\u9fa5]"; Pattern p = Pattern.compile(regEx); Matcher m = p.matcher(str); while (m.find()) { return true; } return false; }
<groupId>com.github.junrar</groupId> <artifactId>junrar</artifactId>
方法二
/** * 采用命令行方式解压文件 * * @param rarPath 压缩文件路径 * @param destDir 解压结果路径 * @param cmdPath WinRAR.exe的路径,也可以在代码中写死 * @return */ public static boolean realExtract(String rarPath, String destDir, String cmdPath) { File rarFile = new File(rarPath); // 解决路径中存在/..格式的路径问题 destDir = new File(destDir).getAbsoluteFile().getAbsolutePath(); while (destDir.contains("..")) { String[] sepList = destDir.split("\\\\"); destDir = ""; for (int i = 0; i < sepList.length; i++) { if (!"..".equals(sepList[i]) && i < sepList.length - 1 && "..".equals(sepList[i + 1])) { i++; } else { destDir += sepList[i] + File.separator; } } } boolean bool = false; if (!rarFile.exists()) { return false; } // 开始调用命令行解压,参数-o+是表示覆盖的意思 String cmd = cmdPath + " X -o+ " + rarFile + " " + destDir; System.out.println(cmd); try { Process proc = Runtime.getRuntime().exec(cmd); if (proc.waitFor() != 0) { if (proc.exitValue() == 0) { bool = false; } } else { bool = true; } } catch (Exception e) { e.printStackTrace(); } rarFile.delete(); return bool; }
Java解压 rar、zip、7z 等压缩包通用工具类
问题
项目中有一个需求,客户端上传压缩包到服务器,需要先解压压缩包,拿到文件后进一步业务处理(保存图片,导入excel表格中的数据等等)。
上传的压缩包有多种格式,可能是 rar 或者 zip,Java 自带的工具类只能解压 zip,rar 需要额外导入其他依赖来解压。
记录下当时项目中用来解压 rar 的代码,该工具类也可以解压 zip 7z 等压缩包。
代码
- pom
<dependency> <groupId>net.sf.sevenzipjbinding</groupId> <artifactId>sevenzipjbinding-all-platforms</artifactId> <version>16.02-2.01</version> </dependency> <dependency> <groupId>net.sf.sevenzipjbinding</groupId> <artifactId>sevenzipjbinding</artifactId> <version>16.02-2.01</version> </dependency>
- 解压工具类
public class UnCompressUtil { private static final Logger logger = Logger.getLogger(UnCompressUtil.class.getCanonicalName()); /** * 解压rar * * @param file rar * @param extractPath 解压路径 */ public static void unCompress(File file, String extractPath) { try{ RandomAccessFile randomAccessFile = new RandomAccessFile(file.getAbsolutePath(), "r"); IInArchive archive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile)); // 解压⽂件路径 File extractDir = new File(extractPath); if (!extractDir.isDirectory()) { extractDir.mkdir(); } int[] in = new int[archive.getNumberOfItems()]; for(int i=0;i<in.length;i++){ in[i] = i; } archive.extract(in, false, new ExtractCallback(archive, extractDir.getAbsolutePath())); archive.close(); randomAccessFile.close(); } catch (IOException e) { e.printStackTrace(); } } private static class ExtractCallback implements IArchiveExtractCallback { private final IInArchive inArchive; private final String extractPath; public ExtractCallback(IInArchive inArchive, String extractPath) { this.inArchive = inArchive; if (!extractPath.endsWith("/") && !extractPath.endsWith("\\")) { extractPath += File.separator; } this.extractPath = extractPath; } @Override public void setTotal(long total) { } @Override public void setCompleted(long complete) { } @Override public ISequentialOutStream getStream(int index, ExtractAskMode extractAskMode) throws SevenZipException { return data -> { String filePath = inArchive.getStringProperty(index, PropID.PATH); FileOutputStream fos = null; try { File path = new File(extractPath + filePath); if(!path.getParentFile().exists()){ path.getParentFile().mkdirs(); } if(!path.exists()){ path.createNewFile(); } fos = new FileOutputStream(path, true); fos.write(data); } catch (IOException e) { logger.log(null, "IOException while extracting " + filePath); } finally{ try { if(fos != null){ fos.flush(); fos.close(); } } catch (IOException e) { logger.log(null, "Could not close FileOutputStream", e); } } return data.length; }; } @Override public void prepareOperation(ExtractAskMode extractAskMode) { } @Override public void setOperationResult(ExtractOperationResult extractOperationResult) { } } }
- 测试类
class UnCompressUtilTest { @Test void unCompress() { String rarPath = "C:\\Users\\XXX\\Desktop\\test.rar"; File file = new File(rarPath); String extractPath = "C:\\Users\\XXX\\Desktop"; UnCompressUtil.unCompress(file, extractPath); } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。