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-11
Java使用單鏈表實(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的異常回滾和事務(wù)的使用詳解,Spring中 @Transactional 注解,默認(rèn)情況下,只對(duì)拋出的RuntimeException 異常,才會(huì)事務(wù)回滾,需要的朋友可以參考下2023-05-05
Java實(shí)現(xiàn)計(jì)算器設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)計(jì)算器設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07
Java8接口中引入default關(guān)鍵字的本質(zhì)原因詳析
Default方法是在java8中引入的關(guān)鍵字,也可稱為Virtual extension methods—虛擬擴(kuò)展方法,這篇文章主要給大家介紹了關(guān)于Java8接口中引入default關(guān)鍵字的本質(zhì)原因,需要的朋友可以參考下2022-01-01
Java實(shí)現(xiàn)分解任意輸入數(shù)的質(zhì)因數(shù)算法示例
這篇文章主要介紹了Java實(shí)現(xiàn)分解任意輸入數(shù)的質(zhì)因數(shù)算法,涉及java數(shù)學(xué)運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2017-10-10

