目錄
一、用到的知識點
二、代碼展示(分解版)
三、代碼展示(整體版)
一、用到的知識點
1.IO流:
????????Input:輸入,通過“輸入流”進行文件的讀取操作
????????Output:輸出,通過“輸出流”進行文件的寫入操作
2.文件操作相關:
????????File類:用于表示文件和目錄的路徑。
????????FileInputStream和FileOutputStream:用于讀取和寫入文件。
3.壓縮文件處理:
????????ZipInputStream:用于讀取 ZIP 壓縮文件的輸入流。
????????ZipEntry:表示 ZIP 壓縮文件中的條目(文件或目錄)。
4.異常處理:
????????FileNotFoundException:當嘗試訪問不存在的文件時拋出。
????????IOException:用于處理輸入輸出操作中的一般性異常。
????????RarException:處理與 RAR 壓縮文件操作相關的特定異常。
5.數據輸入輸出流:
????????InputStream:用于讀取數據的輸入流。
6.集合操作:
????????List:用于存儲文件頭信息的列表。
7.比較器(Comparator):用于對文件頭列表進行排序。
8.第三方庫?commons-io?中的?FileUtils?類:(此jar包在文末)
? ? ? ?用于刪除目錄和復制輸入流到文件。
二、代碼展示(分解版)
步驟1:判斷文件類型
- ????????若是".zip"文件則調用unzip()方法來解壓縮 ZIP 文件,若是".rar"文件則調用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()方法
- 根據輸入的文件路徑創建源文件對象。
- 確定解壓縮后的根目錄路徑,并創建對應的文件對象。
- 如果根目錄已存在,嘗試刪除(包括使用?
FileUtils
?工具類刪除非空目錄),然后重新創建根目錄。- 創建用于讀取 ZIP 格式的輸入流。
- 遍歷壓縮包中的每個條目(子文件或子目錄)。
- 為每個條目創建對應的文件對象。
- 判斷條目是子文件還是子目錄,分別進行創建文件或目錄的操作。
- 對于子文件,創建輸出流,讀取輸入流中的數據并寫入子文件。
- 處理可能出現的文件未找到和輸入輸出異常。
//2.解壓縮zip格式public static void unzip(String path) {//(1)根據原始路徑(字符串),創建源文件(File對象)File sourceFile = new File(path);//(2)根目錄String sourceName = sourceFile.getName();File rootDir = new File(sourceFile.getParent()+"\\"+sourceName.substring(0,sourceName.lastIndexOf(".")));//(3)判斷根目錄是否已經存在if(rootDir.exists()) {//若存在,則刪除rootDir.delete();//只能刪除空目錄//使用commons-io包提供的FileUtils工具類進行刪除try {FileUtils.deleteDirectory(rootDir);} catch (IOException e) {e.printStackTrace();}}//(4)創建根目錄rootDir.mkdir();//(5)ZipInputStream:用于進行zip格式的壓縮輸入流try {ZipInputStream in = new ZipInputStream(new FileInputStream(sourceFile));//(6)遍歷壓縮包中每個子文件子目錄(zipEntry類型的對象)ZipEntry zipEntry = null;while((zipEntry = in.getNextEntry())!=null) {//(7)創建子文件子目錄(File對象)File file = new File(rootDir.getPath()+"\\"+zipEntry.getName());//(8)判斷是子文件還是子目錄(不是子目錄就是子文件)if(zipEntry.isDirectory()) {//物理磁盤創建子目錄file.mkdir();}else {//物理磁盤創建子文件file.createNewFile();//(9)子文件的寫入//讀取當前壓縮包的子文件,并通過輸出流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()方法
- 根據輸入的 RAR 文件路徑創建根目錄的文件對象。
- 判斷根目錄是否存在,如果存在則嘗試刪除(使用?
FileUtils
?處理可能的異常),然后創建根目錄。- 創建用于讀取 RAR 壓縮文件的?
Archive
?對象。- 獲取壓縮文件中的所有子目錄和子文件的?
FileHeader
?對象,并存儲在列表中。- 按照子目錄和子文件的名稱對列表進行排序。
- 遍歷列表中的每個?
FileHeader
?對象。- 根據?
FileHeader
?對象創建對應的文件對象。- 判斷是子目錄還是子文件,分別進行創建目錄或文件的操作。
- 對于子文件,獲取輸入流并使用?
FileUtils
?將輸入流復制到子文件中。- 處理可能出現的 RAR 相關異常和輸入輸出異常。
//3.解壓縮rar格式public static void unrar(String path) {//(1)創建解壓縮的根目錄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)創建Archive對象,用于讀取rar壓縮文件格式try (Archive archive = new Archive(new FileInputStream(path))){//(4)獲取壓縮文件所有子目錄子文件(FileHeader對象)List<FileHeader> fileheaderList = archive.getFileHeaders();//(5)按照子目錄(子文件)名稱排序fileheaderList.sort(new Comparator<FileHeader>() {@Overridepublic 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()) {//物理磁盤創建子目錄f.mkdir();}else {//物理磁盤創建子文件f.createNewFile();//獲取壓縮包中子文件輸入流InputStream in = archive.getInputStream(fd);//復制文件輸入流至子文件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)根據原始路徑(字符串),創建源文件(File對象)File sourceFile = new File(path);//(2)根目錄String sourceName = sourceFile.getName();File rootDir = new File(sourceFile.getParent()+"\\"+sourceName.substring(0,sourceName.lastIndexOf(".")));//(3)判斷根目錄是否已經存在if(rootDir.exists()) {//若存在,則刪除rootDir.delete();//只能刪除空目錄//使用commons-io包提供的FileUtils工具類進行刪除try {FileUtils.deleteDirectory(rootDir);} catch (IOException e) {e.printStackTrace();}}//(4)創建根目錄rootDir.mkdir();//(5)ZipInputStream:用于進行zip格式的壓縮輸入流try {ZipInputStream in = new ZipInputStream(new FileInputStream(sourceFile));//(6)遍歷壓縮包中每個子文件子目錄(zipEntry類型的對象)ZipEntry zipEntry = null;while((zipEntry = in.getNextEntry())!=null) {//(7)創建子文件子目錄(File對象)File file = new File(rootDir.getPath()+"\\"+zipEntry.getName());//(8)判斷是子文件還是子目錄(不是子目錄就是子文件)if(zipEntry.isDirectory()) {//物理磁盤創建子目錄file.mkdir();}else {//物理磁盤創建子文件file.createNewFile();//(9)子文件的寫入//讀取當前壓縮包的子文件,并通過輸出流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)創建解壓縮的根目錄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)創建Archive對象,用于讀取rar壓縮文件格式try (Archive archive = new Archive(new FileInputStream(path))){//(4)獲取壓縮文件所有子目錄子文件(FileHeader對象)List<FileHeader> fileheaderList = archive.getFileHeaders();//(5)按照子目錄(子文件)名稱排序fileheaderList.sort(new Comparator<FileHeader>() {@Overridepublic 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()) {//物理磁盤創建子目錄f.mkdir();}else {//物理磁盤創建子文件f.createNewFile();//獲取壓縮包中子文件輸入流InputStream in = archive.getInputStream(fd);//復制文件輸入流至子文件FileUtils.copyInputStreamToFile(in, f);}}} catch (RarException | IOException e) {e.printStackTrace();}}
}
四、使用場景
? ? 以上提供了兩種常見壓縮格式(ZIP 和 RAR)文件的解壓縮功能。通過判斷輸入文件的格式(根據文件擴展名),調用相應的解壓縮方法(unzip
?或?unrar
),能夠將壓縮文件中的內容正確地解壓到指定的目錄中。
這種功能在很多場景中都非常有用,例如:
- 數據處理和分析:當獲取到壓縮形式的數據時,需要解壓縮來獲取原始數據進行處理和分析。
- 文件傳輸和存儲:在文件傳輸或存儲過程中,壓縮可以節省空間和提高傳輸效率,到達目的地后再解壓縮以恢復原始文件結構。
- 軟件開發:在開發過程中,可能需要處理和整合來自不同來源的壓縮文件資源。
????????總的來說,這段代碼提供了一種靈活且可復用的方式來處理 ZIP 和 RAR 壓縮文件的解壓縮操作,滿足了在各種應用中對壓縮文件進行處理的需求。