Java解壓rar文件的兩種實(shí)現(xiàn)方法
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(); } //判斷文件名有沒(méi)有正則表達(dá)式 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 解壓結(jié)果路徑 * @param cmdPath WinRAR.exe的路徑,也可以在代碼中寫死 * @return */ public static boolean realExtract(String rarPath, String destDir, String cmdPath) { File rarFile = new File(rarPath); // 解決路徑中存在/..格式的路徑問(wèn)題 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; } // 開(kāi)始調(diào)用命令行解壓,參數(shù)-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 等壓縮包通用工具類
問(wèn)題
項(xiàng)目中有一個(gè)需求,客戶端上傳壓縮包到服務(wù)器,需要先解壓壓縮包,拿到文件后進(jìn)一步業(yè)務(wù)處理(保存圖片,導(dǎo)入excel表格中的數(shù)據(jù)等等)。
上傳的壓縮包有多種格式,可能是 rar 或者 zip,Java 自帶的工具類只能解壓 zip,rar 需要額外導(dǎo)入其他依賴來(lái)解壓。
記錄下當(dāng)時(shí)項(xiàng)目中用來(lái)解壓 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) { } } }
- 測(cè)試類
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); } }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java數(shù)據(jù)結(jié)構(gòu)中堆的向下和向上調(diào)整解析
堆是一顆完全二叉樹(shù),在這棵樹(shù)中,所有父節(jié)點(diǎn)都滿足大于等于其子節(jié)點(diǎn)的堆叫大根堆,所有父節(jié)點(diǎn)都滿足小于等于其子節(jié)點(diǎn)的堆叫小根堆。堆雖然是一顆樹(shù),但是通常存放在一個(gè)數(shù)組中,父節(jié)點(diǎn)和孩子節(jié)點(diǎn)的父子關(guān)系通過(guò)數(shù)組下標(biāo)來(lái)確定2021-11-11Java使用單鏈表實(shí)現(xiàn)約瑟夫環(huán)
這篇文章主要為大家詳細(xì)介紹了Java使用單鏈表實(shí)現(xiàn)約瑟夫環(huán),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10關(guān)于SpringBoot的異?;貪L和事務(wù)的使用詳解
這篇文章主要介紹了關(guān)于SpringBoot的異?;貪L和事務(wù)的使用詳解,Spring中 @Transactional 注解,默認(rèn)情況下,只對(duì)拋出的RuntimeException 異常,才會(huì)事務(wù)回滾,需要的朋友可以參考下2023-05-05Java實(shí)現(xiàn)計(jì)算器設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)計(jì)算器設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07Java8接口中引入default關(guān)鍵字的本質(zhì)原因詳析
Default方法是在java8中引入的關(guān)鍵字,也可稱為Virtual extension methods—虛擬擴(kuò)展方法,這篇文章主要給大家介紹了關(guān)于Java8接口中引入default關(guān)鍵字的本質(zhì)原因,需要的朋友可以參考下2022-01-01Java實(shí)現(xiàn)分解任意輸入數(shù)的質(zhì)因數(shù)算法示例
這篇文章主要介紹了Java實(shí)現(xiàn)分解任意輸入數(shù)的質(zhì)因數(shù)算法,涉及java數(shù)學(xué)運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2017-10-10