通過(guò)Java實(shí)現(xiàn)zip文件與rar文件解壓縮的詳細(xì)步驟
一、用到的知識(shí)點(diǎn)
1.IO流:
Input:輸入,通過(guò)“輸入流”進(jìn)行文件的讀取操作
Output:輸出,通過(guò)“輸出流”進(jìn)行文件的寫入操作
2.文件操作相關(guān):
File類:用于表示文件和目錄的路徑。
FileInputStream和FileOutputStream:用于讀取和寫入文件。
3.壓縮文件處理:
ZipInputStream:用于讀取 ZIP 壓縮文件的輸入流。
ZipEntry:表示 ZIP 壓縮文件中的條目(文件或目錄)。
4.異常處理:
FileNotFoundException:當(dāng)嘗試訪問(wèn)不存在的文件時(shí)拋出。
IOException:用于處理輸入輸出操作中的一般性異常。
RarException:處理與 RAR 壓縮文件操作相關(guān)的特定異常。
5.數(shù)據(jù)輸入輸出流:
InputStream:用于讀取數(shù)據(jù)的輸入流。
6.集合操作:
List:用于存儲(chǔ)文件頭信息的列表。
7.比較器(Comparator):用于對(duì)文件頭列表進(jìn)行排序。
8.第三方庫(kù) commons-io 中的 FileUtils 類:(此jar包在文末)
用于刪除目錄和復(fù)制輸入流到文件。
二、代碼展示(分解版)
步驟1:判斷文件類型
- 若是".zip"文件則調(diào)用unzip()方法來(lái)解壓縮 ZIP 文件,若是".rar"文件則調(diào)用unrar()方法來(lái)解壓縮 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)建源文件對(duì)象。
- 確定解壓縮后的根目錄路徑,并創(chuàng)建對(duì)應(yīng)的文件對(duì)象。
- 如果根目錄已存在,嘗試刪除(包括使用
FileUtils
工具類刪除非空目錄),然后重新創(chuàng)建根目錄。 - 創(chuàng)建用于讀取 ZIP 格式的輸入流。
- 遍歷壓縮包中的每個(gè)條目(子文件或子目錄)。
- 為每個(gè)條目創(chuàng)建對(duì)應(yīng)的文件對(duì)象。
- 判斷條目是子文件還是子目錄,分別進(jìn)行創(chuàng)建文件或目錄的操作。
- 對(duì)于子文件,創(chuàng)建輸出流,讀取輸入流中的數(shù)據(jù)并寫入子文件。
- 處理可能出現(xiàn)的文件未找到和輸入輸出異常。
//2.解壓縮zip格式 public static void unzip(String path) { //(1)根據(jù)原始路徑(字符串),創(chuàng)建源文件(File對(duì)象) 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工具類進(jìn)行刪除 try { FileUtils.deleteDirectory(rootDir); } catch (IOException e) { e.printStackTrace(); } } //(4)創(chuàng)建根目錄 rootDir.mkdir(); //(5)ZipInputStream:用于進(jìn)行zip格式的壓縮輸入流 try { ZipInputStream in = new ZipInputStream(new FileInputStream(sourceFile)); //(6)遍歷壓縮包中每個(gè)子文件子目錄(zipEntry類型的對(duì)象) ZipEntry zipEntry = null; while((zipEntry = in.getNextEntry())!=null) { //(7)創(chuàng)建子文件子目錄(File對(duì)象) File file = new File(rootDir.getPath()+"\\"+zipEntry.getName()); //(8)判斷是子文件還是子目錄(不是子目錄就是子文件) if(zipEntry.isDirectory()) { //物理磁盤創(chuàng)建子目錄 file.mkdir(); }else { //物理磁盤創(chuàng)建子文件 file.createNewFile(); //(9)子文件的寫入 //讀取當(dāng)前壓縮包的子文件,并通過(guò)輸出流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)建根目錄的文件對(duì)象。
- 判斷根目錄是否存在,如果存在則嘗試刪除(使用
FileUtils
處理可能的異常),然后創(chuàng)建根目錄。 - 創(chuàng)建用于讀取 RAR 壓縮文件的
Archive
對(duì)象。 - 獲取壓縮文件中的所有子目錄和子文件的
FileHeader
對(duì)象,并存儲(chǔ)在列表中。 - 按照子目錄和子文件的名稱對(duì)列表進(jìn)行排序。
- 遍歷列表中的每個(gè)
FileHeader
對(duì)象。 - 根據(jù)
FileHeader
對(duì)象創(chuàng)建對(duì)應(yīng)的文件對(duì)象。 - 判斷是子目錄還是子文件,分別進(jìn)行創(chuàng)建目錄或文件的操作。
- 對(duì)于子文件,獲取輸入流并使用
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對(duì)象,用于讀取rar壓縮文件格式 try (Archive archive = new Archive(new FileInputStream(path))){ //(4)獲取壓縮文件所有子目錄子文件(FileHeader對(duì)象) 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對(duì)象) 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工具類進(jìn)行刪除 try { FileUtils.deleteDirectory(rootDir); } catch (IOException e) { e.printStackTrace(); } } //(4)創(chuàng)建根目錄 rootDir.mkdir(); //(5)ZipInputStream:用于進(jìn)行zip格式的壓縮輸入流 try { ZipInputStream in = new ZipInputStream(new FileInputStream(sourceFile)); //(6)遍歷壓縮包中每個(gè)子文件子目錄(zipEntry類型的對(duì)象) ZipEntry zipEntry = null; while((zipEntry = in.getNextEntry())!=null) { //(7)創(chuàng)建子文件子目錄(File對(duì)象) File file = new File(rootDir.getPath()+"\\"+zipEntry.getName()); //(8)判斷是子文件還是子目錄(不是子目錄就是子文件) if(zipEntry.isDirectory()) { //物理磁盤創(chuàng)建子目錄 file.mkdir(); }else { //物理磁盤創(chuàng)建子文件 file.createNewFile(); //(9)子文件的寫入 //讀取當(dāng)前壓縮包的子文件,并通過(guò)輸出流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對(duì)象,用于讀取rar壓縮文件格式 try (Archive archive = new Archive(new FileInputStream(path))){ //(4)獲取壓縮文件所有子目錄子文件(FileHeader對(duì)象) 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(); } } }
四、使用場(chǎng)景
以上提供了兩種常見(jiàn)壓縮格式(ZIP 和 RAR)文件的解壓縮功能。通過(guò)判斷輸入文件的格式(根據(jù)文件擴(kuò)展名),調(diào)用相應(yīng)的解壓縮方法(unzip
或 unrar
),能夠?qū)嚎s文件中的內(nèi)容正確地解壓到指定的目錄中。
這種功能在很多場(chǎng)景中都非常有用,例如:
- 數(shù)據(jù)處理和分析:當(dāng)獲取到壓縮形式的數(shù)據(jù)時(shí),需要解壓縮來(lái)獲取原始數(shù)據(jù)進(jìn)行處理和分析。
- 文件傳輸和存儲(chǔ):在文件傳輸或存儲(chǔ)過(guò)程中,壓縮可以節(jié)省空間和提高傳輸效率,到達(dá)目的地后再解壓縮以恢復(fù)原始文件結(jié)構(gòu)。
- 軟件開(kāi)發(fā):在開(kāi)發(fā)過(guò)程中,可能需要處理和整合來(lái)自不同來(lái)源的壓縮文件資源。
總的來(lái)說(shuō),這段代碼提供了一種靈活且可復(fù)用的方式來(lái)處理 ZIP 和 RAR 壓縮文件的解壓縮操作,滿足了在各種應(yīng)用中對(duì)壓縮文件進(jìn)行處理的需求。
以上就是通過(guò)Java實(shí)現(xiàn)zip文件與rar文件解壓縮的詳細(xì)步驟的詳細(xì)內(nèi)容,更多關(guān)于Java實(shí)現(xiàn)zip與rar文件解壓縮的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot靜態(tài)資源css,js,img配置方案
這篇文章主要介紹了SpringBoot靜態(tài)資源css,js,img配置方案,下文給大家分享了三種解決方案,需要的朋友可以參考下2017-07-07idea使用spring Initializr 快速搭建springboot項(xiàng)目遇到的坑
這篇文章主要介紹了idea使用spring Initializr 快速搭建springboot項(xiàng)目遇到的坑,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11springBoot+dubbo+zookeeper實(shí)現(xiàn)分布式開(kāi)發(fā)應(yīng)用的項(xiàng)目實(shí)踐
本文主要介紹了springBoot+dubbo+zookeeper實(shí)現(xiàn)分布式開(kāi)發(fā)應(yīng)用的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03解讀Integer類的parseInt和valueOf的區(qū)別
這篇文章主要介紹了解讀Integer類的parseInt和valueOf的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11Java使用正則表達(dá)式驗(yàn)證手機(jī)號(hào)和電話號(hào)碼的方法
今天小編就為大家分享一篇關(guān)于Java使用正則表達(dá)式驗(yàn)證手機(jī)號(hào)和電話號(hào)碼的方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12Java設(shè)計(jì)模式之命令模式詳細(xì)解析
這篇文章主要介紹了Java設(shè)計(jì)模式之命令模式詳細(xì)解析,命令模式將請(qǐng)求封裝成對(duì)象,以便使用不同的請(qǐng)求、隊(duì)列或者日志來(lái)參數(shù)化其他對(duì)象,同時(shí)也支持可撤銷的操作,需要的朋友可以參考下2024-01-01BeanFactory和FactoryBean的區(qū)別示例詳解
這篇文章主要為大家介紹了BeanFactory和FactoryBean的區(qū)別示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10