通過Java實現(xiàn)zip文件與rar文件解壓縮的詳細步驟
一、用到的知識點
1.IO流:
Input:輸入,通過“輸入流”進行文件的讀取操作
Output:輸出,通過“輸出流”進行文件的寫入操作
2.文件操作相關(guān):
File類:用于表示文件和目錄的路徑。
FileInputStream和FileOutputStream:用于讀取和寫入文件。
3.壓縮文件處理:
ZipInputStream:用于讀取 ZIP 壓縮文件的輸入流。
ZipEntry:表示 ZIP 壓縮文件中的條目(文件或目錄)。
4.異常處理:
FileNotFoundException:當(dāng)嘗試訪問不存在的文件時拋出。
IOException:用于處理輸入輸出操作中的一般性異常。
RarException:處理與 RAR 壓縮文件操作相關(guān)的特定異常。
5.數(shù)據(jù)輸入輸出流:
InputStream:用于讀取數(shù)據(jù)的輸入流。
6.集合操作:
List:用于存儲文件頭信息的列表。
7.比較器(Comparator):用于對文件頭列表進行排序。
8.第三方庫 commons-io 中的 FileUtils 類:(此jar包在文末)
用于刪除目錄和復(fù)制輸入流到文件。
二、代碼展示(分解版)
步驟1:判斷文件類型
- 若是".zip"文件則調(diào)用unzip()方法來解壓縮 ZIP 文件,若是".rar"文件則調(diào)用unrar()方法來解壓縮 RAR 文件
//指定文件夾
String Path = “D:\\...\\xxxx.zip”
String Path = “D:\\...\\xxxx.rar”
}
//1.判斷文件類型
if(path.endsWith(".zip")) {
unzip(path);
}else if(path.endsWith(".rar")) {
unrar(path);
}
}步驟2:定義unzip()方法
- 根據(jù)輸入的文件路徑創(chuàng)建源文件對象。
- 確定解壓縮后的根目錄路徑,并創(chuàng)建對應(yīng)的文件對象。
- 如果根目錄已存在,嘗試刪除(包括使用
FileUtils工具類刪除非空目錄),然后重新創(chuàng)建根目錄。 - 創(chuàng)建用于讀取 ZIP 格式的輸入流。
- 遍歷壓縮包中的每個條目(子文件或子目錄)。
- 為每個條目創(chuàng)建對應(yīng)的文件對象。
- 判斷條目是子文件還是子目錄,分別進行創(chuàng)建文件或目錄的操作。
- 對于子文件,創(chuàng)建輸出流,讀取輸入流中的數(shù)據(jù)并寫入子文件。
- 處理可能出現(xiàn)的文件未找到和輸入輸出異常。
//2.解壓縮zip格式
public static void unzip(String path) {
//(1)根據(jù)原始路徑(字符串),創(chuàng)建源文件(File對象)
File sourceFile = new File(path);
//(2)根目錄
String sourceName = sourceFile.getName();
File rootDir = new File(sourceFile.getParent()+"\\"+sourceName.substring(0,sourceName.lastIndexOf(".")));
//(3)判斷根目錄是否已經(jīng)存在
if(rootDir.exists()) {
//若存在,則刪除
rootDir.delete();//只能刪除空目錄
//使用commons-io包提供的FileUtils工具類進行刪除
try {
FileUtils.deleteDirectory(rootDir);
} catch (IOException e) {
e.printStackTrace();
}
}
//(4)創(chuàng)建根目錄
rootDir.mkdir();
//(5)ZipInputStream:用于進行zip格式的壓縮輸入流
try {
ZipInputStream in = new ZipInputStream(new FileInputStream(sourceFile));
//(6)遍歷壓縮包中每個子文件子目錄(zipEntry類型的對象)
ZipEntry zipEntry = null;
while((zipEntry = in.getNextEntry())!=null) {
//(7)創(chuàng)建子文件子目錄(File對象)
File file = new File(rootDir.getPath()+"\\"+zipEntry.getName());
//(8)判斷是子文件還是子目錄(不是子目錄就是子文件)
if(zipEntry.isDirectory()) {
//物理磁盤創(chuàng)建子目錄
file.mkdir();
}else {
//物理磁盤創(chuàng)建子文件
file.createNewFile();
//(9)子文件的寫入
//讀取當(dāng)前壓縮包的子文件,并通過輸出流out寫入新子文件中
try (FileOutputStream out = new FileOutputStream(file)) {
byte[] buff = new byte[1024];
int len = -1;
while((len = in.read(buff))!=-1) {
out.write(buff,0,len);
}
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}步驟3:定義unrar()方法
- 根據(jù)輸入的 RAR 文件路徑創(chuàng)建根目錄的文件對象。
- 判斷根目錄是否存在,如果存在則嘗試刪除(使用
FileUtils處理可能的異常),然后創(chuàng)建根目錄。 - 創(chuàng)建用于讀取 RAR 壓縮文件的
Archive對象。 - 獲取壓縮文件中的所有子目錄和子文件的
FileHeader對象,并存儲在列表中。 - 按照子目錄和子文件的名稱對列表進行排序。
- 遍歷列表中的每個
FileHeader對象。 - 根據(jù)
FileHeader對象創(chuàng)建對應(yīng)的文件對象。 - 判斷是子目錄還是子文件,分別進行創(chuàng)建目錄或文件的操作。
- 對于子文件,獲取輸入流并使用
FileUtils將輸入流復(fù)制到子文件中。 - 處理可能出現(xiàn)的 RAR 相關(guān)異常和輸入輸出異常。
//3.解壓縮rar格式
public static void unrar(String path) {
//(1)創(chuàng)建解壓縮的根目錄
File rarFile = new File(path);
File rootDir = new File(rarFile.getParent()+"\\"+rarFile.getName().substring(0,rarFile.getName().lastIndexOf(".")));
//(2)判斷是否存在
if(rootDir.exists()) {
try {
FileUtils.deleteDirectory(rootDir);
} catch (IOException e) {
e.printStackTrace();
}
}
rootDir.mkdir();
//(3)創(chuàng)建Archive對象,用于讀取rar壓縮文件格式
try (Archive archive = new Archive(new FileInputStream(path))){
//(4)獲取壓縮文件所有子目錄子文件(FileHeader對象)
List<FileHeader> fileheaderList = archive.getFileHeaders();
//(5)按照子目錄(子文件)名稱排序
fileheaderList.sort(new Comparator<FileHeader>() {
@Override
public int compare(FileHeader o1, FileHeader o2) {
return o1.getFileName().compareTo(o2.getFileName());
}
});
//(6)遍歷子目錄子文件
for(FileHeader fd : fileheaderList) {
File f = new File(rootDir.getPath()+"\\"+fd.getFileName());
if(fd.isDirectory()) {
//物理磁盤創(chuàng)建子目錄
f.mkdir();
}else {
//物理磁盤創(chuàng)建子文件
f.createNewFile();
//獲取壓縮包中子文件輸入流
InputStream in = archive.getInputStream(fd);
//復(fù)制文件輸入流至子文件
FileUtils.copyInputStreamToFile(in, f);
}
}
} catch (RarException | IOException e) {
e.printStackTrace();
}
}三、代碼展示(整體版)
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Comparator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.io.FileUtils;
import com.github.junrar.Archive;
import com.github.junrar.exception.RarException;
import com.github.junrar.rarfile.FileHeader;
public class Test {
//指定文件夾
String Path = “D:\\...\\xxxx.zip”
String Path = “D:\\...\\xxxx.rar”
}
//1.判斷文件類型
if(path.endsWith(".zip")) {
unzip(path);
}else if(path.endsWith(".rar")) {
unrar(path);
}
}
//2.解壓縮zip格式
public static void unzip(String path) {
//(1)根據(jù)原始路徑(字符串),創(chuàng)建源文件(File對象)
File sourceFile = new File(path);
//(2)根目錄
String sourceName = sourceFile.getName();
File rootDir = new File(sourceFile.getParent()+"\\"+sourceName.substring(0,sourceName.lastIndexOf(".")));
//(3)判斷根目錄是否已經(jīng)存在
if(rootDir.exists()) {
//若存在,則刪除
rootDir.delete();//只能刪除空目錄
//使用commons-io包提供的FileUtils工具類進行刪除
try {
FileUtils.deleteDirectory(rootDir);
} catch (IOException e) {
e.printStackTrace();
}
}
//(4)創(chuàng)建根目錄
rootDir.mkdir();
//(5)ZipInputStream:用于進行zip格式的壓縮輸入流
try {
ZipInputStream in = new ZipInputStream(new FileInputStream(sourceFile));
//(6)遍歷壓縮包中每個子文件子目錄(zipEntry類型的對象)
ZipEntry zipEntry = null;
while((zipEntry = in.getNextEntry())!=null) {
//(7)創(chuàng)建子文件子目錄(File對象)
File file = new File(rootDir.getPath()+"\\"+zipEntry.getName());
//(8)判斷是子文件還是子目錄(不是子目錄就是子文件)
if(zipEntry.isDirectory()) {
//物理磁盤創(chuàng)建子目錄
file.mkdir();
}else {
//物理磁盤創(chuàng)建子文件
file.createNewFile();
//(9)子文件的寫入
//讀取當(dāng)前壓縮包的子文件,并通過輸出流out寫入新子文件中
try (FileOutputStream out = new FileOutputStream(file)) {
byte[] buff = new byte[1024];
int len = -1;
while((len = in.read(buff))!=-1) {
out.write(buff,0,len);
}
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//3.解壓縮rar格式
public static void unrar(String path) {
//(1)創(chuàng)建解壓縮的根目錄
File rarFile = new File(path);
File rootDir = new File(rarFile.getParent()+"\\"+rarFile.getName().substring(0,rarFile.getName().lastIndexOf(".")));
//(2)判斷是否存在
if(rootDir.exists()) {
try {
FileUtils.deleteDirectory(rootDir);
} catch (IOException e) {
e.printStackTrace();
}
}
rootDir.mkdir();
//(3)創(chuàng)建Archive對象,用于讀取rar壓縮文件格式
try (Archive archive = new Archive(new FileInputStream(path))){
//(4)獲取壓縮文件所有子目錄子文件(FileHeader對象)
List<FileHeader> fileheaderList = archive.getFileHeaders();
//(5)按照子目錄(子文件)名稱排序
fileheaderList.sort(new Comparator<FileHeader>() {
@Override
public int compare(FileHeader o1, FileHeader o2) {
return o1.getFileName().compareTo(o2.getFileName());
}
});
//(6)遍歷子目錄子文件
for(FileHeader fd : fileheaderList) {
File f = new File(rootDir.getPath()+"\\"+fd.getFileName());
if(fd.isDirectory()) {
//物理磁盤創(chuàng)建子目錄
f.mkdir();
}else {
//物理磁盤創(chuàng)建子文件
f.createNewFile();
//獲取壓縮包中子文件輸入流
InputStream in = archive.getInputStream(fd);
//復(fù)制文件輸入流至子文件
FileUtils.copyInputStreamToFile(in, f);
}
}
} catch (RarException | IOException e) {
e.printStackTrace();
}
}
}
四、使用場景
以上提供了兩種常見壓縮格式(ZIP 和 RAR)文件的解壓縮功能。通過判斷輸入文件的格式(根據(jù)文件擴展名),調(diào)用相應(yīng)的解壓縮方法(unzip 或 unrar),能夠?qū)嚎s文件中的內(nèi)容正確地解壓到指定的目錄中。
這種功能在很多場景中都非常有用,例如:
- 數(shù)據(jù)處理和分析:當(dāng)獲取到壓縮形式的數(shù)據(jù)時,需要解壓縮來獲取原始數(shù)據(jù)進行處理和分析。
- 文件傳輸和存儲:在文件傳輸或存儲過程中,壓縮可以節(jié)省空間和提高傳輸效率,到達目的地后再解壓縮以恢復(fù)原始文件結(jié)構(gòu)。
- 軟件開發(fā):在開發(fā)過程中,可能需要處理和整合來自不同來源的壓縮文件資源。
總的來說,這段代碼提供了一種靈活且可復(fù)用的方式來處理 ZIP 和 RAR 壓縮文件的解壓縮操作,滿足了在各種應(yīng)用中對壓縮文件進行處理的需求。
以上就是通過Java實現(xiàn)zip文件與rar文件解壓縮的詳細步驟的詳細內(nèi)容,更多關(guān)于Java實現(xiàn)zip與rar文件解壓縮的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot靜態(tài)資源css,js,img配置方案
這篇文章主要介紹了SpringBoot靜態(tài)資源css,js,img配置方案,下文給大家分享了三種解決方案,需要的朋友可以參考下2017-07-07
idea使用spring Initializr 快速搭建springboot項目遇到的坑
這篇文章主要介紹了idea使用spring Initializr 快速搭建springboot項目遇到的坑,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11
springBoot+dubbo+zookeeper實現(xiàn)分布式開發(fā)應(yīng)用的項目實踐
本文主要介紹了springBoot+dubbo+zookeeper實現(xiàn)分布式開發(fā)應(yīng)用的項目實踐,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03
解讀Integer類的parseInt和valueOf的區(qū)別
這篇文章主要介紹了解讀Integer類的parseInt和valueOf的區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11
BeanFactory和FactoryBean的區(qū)別示例詳解
這篇文章主要為大家介紹了BeanFactory和FactoryBean的區(qū)別示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10

