2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Table of contents
2. Code display (decomposed version)
3. Code display (overall version)
1.IO stream:
Input: Input, read files through the "input stream"
Output: Output, write files through the "output stream"
2. File operation related:
File class: used to represent paths to files and directories.
FileInputStream and FileOutputStream: used to read and write files.
3. Compressed file processing:
ZipInputStream: An input stream used to read ZIP compressed files.
ZipEntry: Represents an entry (file or directory) in a ZIP compressed file.
4. Exception handling:
FileNotFoundException: Thrown when trying to access a file that does not exist.
IOException: Used to handle general exceptions in input and output operations.
RarException: Handles specific exceptions related to RAR archive operations.
5. Data input and output flow:
InputStream: Input stream used to read data.
6. Collection operations:
List: A list used to store file header information.
7. Comparator:Used to sort the file header list.
8. FileUtils class in the third-party library commons-io:(This jar package is at the end of the article)
Used to delete directories and copy input streams to files.
Step 1: Determine the file type
- If it is a ".zip" file, the unzip() method is called to decompress the ZIP file. If it is a ".rar" file, the unrar() method is called to decompress the RAR file.
- //指定文件夹
- String Path = “D:\...\xxxx.zip”
- String Path = “D:\...\xxxx.rar”
- }
- //1.判断文件类型
- if(path.endsWith(".zip")) {
- unzip(path);
- }else if(path.endsWith(".rar")) {
- unrar(path);
- }
- }
Step 2: Define the unzip() method
- Create a source file object based on the input file path.
- Determine the root directory path after decompression and create the corresponding file object.
- If the root directory already exists, try deleting it (including using
FileUtils
Tools class to delete non-empty directories) and then recreate the root directory.- Creates an input stream for reading the ZIP format.
- Iterate over each entry (subfile or subdirectory) in the archive.
- For each entry, a corresponding file object is created.
- Determine whether the entry is a subfile or subdirectory, and create the file or directory respectively.
- For a subfile, create an output stream, read the data from the input stream and write it to the subfile.
- Handle possible file not found and input and output exceptions.
- //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();
- }
- }
Step 3: Define the unrar() method
- Creates a file object for the root directory according to the input RAR file path.
- Determine whether the root directory exists, and if so, try to delete it (using
FileUtils
Handle possible exceptions), and then create the root directory.- Create a program for reading RAR archives
Archive
object.- Get all subdirectories and subfiles in the compressed file
FileHeader
objects and store them in a list.- Sort the list by the names of the subdirectories and subfiles.
- Iterate through each
FileHeader
object.- according to
FileHeader
Object creates the corresponding file object.- Determine whether it is a subdirectory or a subfile, and create the directory or file respectively.
- For subfiles, get the input stream and use
FileUtils
Copies the input stream into a subfile.- Handle possible RAR-related exceptions and input/output exceptions.
- //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>() {
- @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()) {
- //物理磁盘创建子目录
- 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>() {
- @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()) {
- //物理磁盘创建子目录
- f.mkdir();
- }else {
- //物理磁盘创建子文件
- f.createNewFile();
-
- //获取压缩包中子文件输入流
- InputStream in = archive.getInputStream(fd);
-
- //复制文件输入流至子文件
- FileUtils.copyInputStreamToFile(in, f);
- }
- }
-
- } catch (RarException | IOException e) {
- e.printStackTrace();
- }
- }
- }
-
The above provides two common compression formats (ZIP and RAR) file decompression functions. By judging the format of the input file (based on the file extension), calling the corresponding decompression method (unzip
orunrar
), can correctly decompress the contents of the compressed file into the specified directory.
This feature is very useful in many scenarios, such as:
In general, this code provides a flexible and reusable way to handle the decompression operation of ZIP and RAR compressed files, meeting the needs of processing compressed files in various applications.