通过Java实现zip文件与rar文件解压缩的详细步骤
作者:冷酷无情小美
一、用到的知识点
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
),能够将压缩文件中的内容正确地解压到指定的目录中。
这种功能在很多场景中都非常有用,例如:
- 数据处理和分析:当获取到压缩形式的数据时,需要解压缩来获取原始数据进行处理和分析。
- 文件传输和存储:在文件传输或存储过程中,压缩可以节省空间和提高传输效率,到达目的地后再解压缩以恢复原始文件结构。
- 软件开发:在开发过程中,可能需要处理和整合来自不同来源的压缩文件资源。
总的来说,这段代码提供了一种灵活且可复用的方式来处理 ZIP 和 RAR 压缩文件的解压缩操作,满足了在各种应用中对压缩文件进行处理的需求。
以上就是通过Java实现zip文件与rar文件解压缩的详细步骤的详细内容,更多关于Java实现zip与rar文件解压缩的资料请关注脚本之家其它相关文章!