如何通过 Java 来完成 zip 文件与 rar 文件的解压缩?

目录

一、用到的知识点

二、代码展示(分解版)

步骤1:判断文件类型

步骤2:定义unzip()方法

 步骤3:定义unrar()方法

三、代码展示(整体版)

四、使用场景


一、用到的知识点

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>() {
				@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();
		}
	}
}

四、使用场景

    以上提供了两种常见压缩格式(ZIP 和 RAR)文件的解压缩功能。通过判断输入文件的格式(根据文件扩展名),调用相应的解压缩方法(unzip 或 unrar),能够将压缩文件中的内容正确地解压到指定的目录中。

这种功能在很多场景中都非常有用,例如:

  1. 数据处理和分析:当获取到压缩形式的数据时,需要解压缩来获取原始数据进行处理和分析。
  2. 文件传输和存储:在文件传输或存储过程中,压缩可以节省空间和提高传输效率,到达目的地后再解压缩以恢复原始文件结构。
  3. 软件开发:在开发过程中,可能需要处理和整合来自不同来源的压缩文件资源。

        总的来说,这段代码提供了一种灵活且可复用的方式来处理 ZIP 和 RAR 压缩文件的解压缩操作,满足了在各种应用中对压缩文件进行处理的需求。

解压多层ZIP包,可以使用JavaZipInputStream和ZipEntry类来实现。下面是一个简单的Java代码示例,可以解压多层ZIP包: ``` import java.io.*; import java.util.zip.*; public class UnzipMultiLayerZip { public static void main(String[] args) throws IOException { String zipFilePath = "path/to/multi-layer-zip-file.zip"; String destDirectory = "path/to/destination/folder/"; unzipMultiLayerZip(zipFilePath, destDirectory); } public static void unzipMultiLayerZip(String zipFilePath, String destDirectory) throws IOException { byte[] buffer = new byte[1024]; FileInputStream fis = new FileInputStream(zipFilePath); ZipInputStream zis = new ZipInputStream(fis); ZipEntry zipEntry = zis.getNextEntry(); while (zipEntry != null) { String fileName = zipEntry.getName(); if (zipEntry.isDirectory()) { File newFolder = new File(destDirectory + File.separator + fileName); newFolder.mkdirs(); zipEntry = zis.getNextEntry(); continue; } File newFile = new File(destDirectory + File.separator + fileName); new File(newFile.getParent()).mkdirs(); FileOutputStream fos = new FileOutputStream(newFile); int len; while ((len = zis.read(buffer)) > 0) { fos.write(buffer, 0, len); } fos.close(); zipEntry = zis.getNextEntry(); } zis.closeEntry(); zis.close(); fis.close(); } } ``` 在这个示例中,我们使用ZipInputStream和ZipEntry类来遍历ZIP文件中的所有条目,并将它们解压到指定的目录中。如果条目是一个目录,则我们创建一个相应的文件夹,并继续遍历。否则,我们创建一个新文件,并将其内容从ZipInputStream中读取并写入该文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冷酷无情小美

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值