Compartir tecnología

¿Cómo descomprimir archivos zip y rar a través de Java?

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Tabla de contenido

1. Puntos de conocimiento utilizados

2. Visualización de código (versión descompuesta)

3. Visualización de código (versión general)


1. Puntos de conocimiento utilizados

1. Flujo IO:

Entrada: entrada, lectura de archivos a través del "flujo de entrada"

Salida: Salida, escribir archivos a través del "flujo de salida"

2. Relacionado con la operación de archivos:

Clase de archivo: se utiliza para representar rutas a archivos y directorios.

FileInputStream y FileOutputStream: se utilizan para leer y escribir archivos.

3. Procesamiento de archivos comprimidos:

ZipInputStream: flujo de entrada para leer archivos comprimidos ZIP.

ZipEntry: Representa una entrada (archivo o directorio) en un archivo comprimido ZIP.

4. Manejo de excepciones:

FileNotFoundException: se produce al intentar acceder a un archivo que no existe.

IOException: se utiliza para manejar excepciones generales en operaciones de entrada y salida.

RarException: maneja excepciones específicas relacionadas con las operaciones de archivo RAR.

5. Flujos de entrada y salida de datos:

InputStream: flujo de entrada para leer datos.

6. Operaciones de cobranza:

Lista: una lista utilizada para almacenar información del encabezado del archivo.

7. Comparador:Se utiliza para ordenar la lista de encabezados de archivos.

8. Clase FileUtils en la biblioteca de terceros commons-io:(Este paquete jar está al final del artículo.)

Se utiliza para eliminar directorios y copiar flujos de entrada a archivos.

2. Visualización de código (versión descompuesta)

Paso 1: determine el tipo de archivo

  • Si es un archivo ".zip", llame al método unzip() para descomprimir el archivo ZIP. Si es un archivo ".rar", llame al método unrar() para descomprimir el archivo RAR.
  1. //指定文件夹
  2. String Path = “D:\...\xxxx.zip”
  3. String Path = “D:\...\xxxx.rar”
  4. }
  5. //1.判断文件类型
  6. if(path.endsWith(".zip")) {
  7. unzip(path);
  8. }else if(path.endsWith(".rar")) {
  9. unrar(path);
  10. }
  11. }

Paso 2: definir el método descomprimir()

  • Crea un objeto de archivo fuente basado en la ruta del archivo de entrada.
  • Determine la ruta del directorio raíz descomprimido y cree el objeto de archivo correspondiente.
  • Si el directorio raíz ya existe, intente eliminarlo (incluido el usoFileUtilsLa clase de utilidad elimina directorios que no están vacíos) y luego recrea el directorio raíz.
  • Cree un flujo de entrada para leer el formato ZIP.
  • Itere a través de cada entrada (subarchivo o subdirectorio) en el archivo.
  • Cree un objeto de archivo correspondiente para cada entrada.
  • Determine si la entrada es un subarchivo o un subdirectorio y cree el archivo o directorio respectivamente.
  • Para subarchivos, cree un flujo de salida, lea datos del flujo de entrada y escriba en el subarchivo.
  • Manejar posibles archivos no encontrados y excepciones de entrada y salida.
  1. //2.解压缩zip格式
  2. public static void unzip(String path) {
  3. //(1)根据原始路径(字符串),创建源文件(File对象)
  4. File sourceFile = new File(path);
  5. //(2)根目录
  6. String sourceName = sourceFile.getName();
  7. File rootDir = new File(sourceFile.getParent()+"\"+sourceName.substring(0,sourceName.lastIndexOf(".")));
  8. //(3)判断根目录是否已经存在
  9. if(rootDir.exists()) {
  10. //若存在,则删除
  11. rootDir.delete();//只能删除空目录
  12. //使用commons-io包提供的FileUtils工具类进行删除
  13. try {
  14. FileUtils.deleteDirectory(rootDir);
  15. } catch (IOException e) {
  16. e.printStackTrace();
  17. }
  18. }
  19. //(4)创建根目录
  20. rootDir.mkdir();
  21. //(5)ZipInputStream:用于进行zip格式的压缩输入流
  22. try {
  23. ZipInputStream in = new ZipInputStream(new FileInputStream(sourceFile));
  24. //(6)遍历压缩包中每个子文件子目录(zipEntry类型的对象)
  25. ZipEntry zipEntry = null;
  26. while((zipEntry = in.getNextEntry())!=null) {
  27. //(7)创建子文件子目录(File对象)
  28. File file = new File(rootDir.getPath()+"\"+zipEntry.getName());
  29. //(8)判断是子文件还是子目录(不是子目录就是子文件)
  30. if(zipEntry.isDirectory()) {
  31. //物理磁盘创建子目录
  32. file.mkdir();
  33. }else {
  34. //物理磁盘创建子文件
  35. file.createNewFile();
  36. //(9)子文件的写入
  37. //读取当前压缩包的子文件,并通过输出流out写入新子文件中
  38. try (FileOutputStream out = new FileOutputStream(file)) {
  39. byte[] buff = new byte[1024];
  40. int len = -1;
  41. while((len = in.read(buff))!=-1) {
  42. out.write(buff,0,len);
  43. }
  44. }
  45. }
  46. }
  47. } catch (FileNotFoundException e) {
  48. e.printStackTrace();
  49. } catch (IOException e) {
  50. e.printStackTrace();
  51. }
  52. }

Paso 3: Definir el método unrar()

  • Cree un objeto de archivo del directorio raíz según la ruta del archivo RAR de entrada.
  • Determine si el directorio raíz existe y, si existe, intente eliminarlo (useFileUtilsmanejar posibles excepciones) y luego crear el directorio raíz.
  • Cree un archivo para leer archivos comprimidos RARArchiveobjeto.
  • Obtenga todos los subdirectorios y subarchivos en un archivo comprimidoFileHeaderobjeto y almacenado en una lista.
  • Ordene la lista por los nombres de subdirectorios y subarchivos.
  • Iterar sobre cada elemento de la lista.FileHeaderobjeto.
  • de acuerdo aFileHeaderObjeto crea el objeto de archivo correspondiente.
  • Determine si es un subdirectorio o un subarchivo y cree el directorio o archivo respectivamente.
  • Para subarchivos, obtenga el flujo de entrada y useFileUtilsCopia el flujo de entrada en un subarchivo.
  • Manejar posibles excepciones relacionadas con RAR y excepciones de entrada y salida.
  1. //3.解压缩rar格式
  2. public static void unrar(String path) {
  3. //(1)创建解压缩的根目录
  4. File rarFile = new File(path);
  5. File rootDir = new File(rarFile.getParent()+"\"+rarFile.getName().substring(0,rarFile.getName().lastIndexOf(".")));
  6. //(2)判断是否存在
  7. if(rootDir.exists()) {
  8. try {
  9. FileUtils.deleteDirectory(rootDir);
  10. } catch (IOException e) {
  11. e.printStackTrace();
  12. }
  13. }
  14. rootDir.mkdir();
  15. //(3)创建Archive对象,用于读取rar压缩文件格式
  16. try (Archive archive = new Archive(new FileInputStream(path))){
  17. //(4)获取压缩文件所有子目录子文件(FileHeader对象)
  18. List<FileHeader> fileheaderList = archive.getFileHeaders();
  19. //(5)按照子目录(子文件)名称排序
  20. fileheaderList.sort(new Comparator<FileHeader>() {
  21. @Override
  22. public int compare(FileHeader o1, FileHeader o2) {
  23. return o1.getFileName().compareTo(o2.getFileName());
  24. }
  25. });
  26. //(6)遍历子目录子文件
  27. for(FileHeader fd : fileheaderList) {
  28. File f = new File(rootDir.getPath()+"\"+fd.getFileName());
  29. if(fd.isDirectory()) {
  30. //物理磁盘创建子目录
  31. f.mkdir();
  32. }else {
  33. //物理磁盘创建子文件
  34. f.createNewFile();
  35. //获取压缩包中子文件输入流
  36. InputStream in = archive.getInputStream(fd);
  37. //复制文件输入流至子文件
  38. FileUtils.copyInputStreamToFile(in, f);
  39. }
  40. }
  41. } catch (RarException | IOException e) {
  42. e.printStackTrace();
  43. }
  44. }

3. Visualización de código (versión general)

  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.util.Comparator;
  8. import java.util.List;
  9. import java.util.zip.ZipEntry;
  10. import java.util.zip.ZipInputStream;
  11. import org.apache.commons.io.FileUtils;
  12. import com.github.junrar.Archive;
  13. import com.github.junrar.exception.RarException;
  14. import com.github.junrar.rarfile.FileHeader;
  15. public class Test {
  16. //指定文件夹
  17. String Path = “D:\...\xxxx.zip”
  18. String Path = “D:\...\xxxx.rar”
  19. }
  20. //1.判断文件类型
  21. if(path.endsWith(".zip")) {
  22. unzip(path);
  23. }else if(path.endsWith(".rar")) {
  24. unrar(path);
  25. }
  26. }
  27. //2.解压缩zip格式
  28. public static void unzip(String path) {
  29. //(1)根据原始路径(字符串),创建源文件(File对象)
  30. File sourceFile = new File(path);
  31. //(2)根目录
  32. String sourceName = sourceFile.getName();
  33. File rootDir = new File(sourceFile.getParent()+"\"+sourceName.substring(0,sourceName.lastIndexOf(".")));
  34. //(3)判断根目录是否已经存在
  35. if(rootDir.exists()) {
  36. //若存在,则删除
  37. rootDir.delete();//只能删除空目录
  38. //使用commons-io包提供的FileUtils工具类进行删除
  39. try {
  40. FileUtils.deleteDirectory(rootDir);
  41. } catch (IOException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45. //(4)创建根目录
  46. rootDir.mkdir();
  47. //(5)ZipInputStream:用于进行zip格式的压缩输入流
  48. try {
  49. ZipInputStream in = new ZipInputStream(new FileInputStream(sourceFile));
  50. //(6)遍历压缩包中每个子文件子目录(zipEntry类型的对象)
  51. ZipEntry zipEntry = null;
  52. while((zipEntry = in.getNextEntry())!=null) {
  53. //(7)创建子文件子目录(File对象)
  54. File file = new File(rootDir.getPath()+"\"+zipEntry.getName());
  55. //(8)判断是子文件还是子目录(不是子目录就是子文件)
  56. if(zipEntry.isDirectory()) {
  57. //物理磁盘创建子目录
  58. file.mkdir();
  59. }else {
  60. //物理磁盘创建子文件
  61. file.createNewFile();
  62. //(9)子文件的写入
  63. //读取当前压缩包的子文件,并通过输出流out写入新子文件中
  64. try (FileOutputStream out = new FileOutputStream(file)) {
  65. byte[] buff = new byte[1024];
  66. int len = -1;
  67. while((len = in.read(buff))!=-1) {
  68. out.write(buff,0,len);
  69. }
  70. }
  71. }
  72. }
  73. } catch (FileNotFoundException e) {
  74. e.printStackTrace();
  75. } catch (IOException e) {
  76. e.printStackTrace();
  77. }
  78. }
  79. //3.解压缩rar格式
  80. public static void unrar(String path) {
  81. //(1)创建解压缩的根目录
  82. File rarFile = new File(path);
  83. File rootDir = new File(rarFile.getParent()+"\"+rarFile.getName().substring(0,rarFile.getName().lastIndexOf(".")));
  84. //(2)判断是否存在
  85. if(rootDir.exists()) {
  86. try {
  87. FileUtils.deleteDirectory(rootDir);
  88. } catch (IOException e) {
  89. e.printStackTrace();
  90. }
  91. }
  92. rootDir.mkdir();
  93. //(3)创建Archive对象,用于读取rar压缩文件格式
  94. try (Archive archive = new Archive(new FileInputStream(path))){
  95. //(4)获取压缩文件所有子目录子文件(FileHeader对象)
  96. List<FileHeader> fileheaderList = archive.getFileHeaders();
  97. //(5)按照子目录(子文件)名称排序
  98. fileheaderList.sort(new Comparator<FileHeader>() {
  99. @Override
  100. public int compare(FileHeader o1, FileHeader o2) {
  101. return o1.getFileName().compareTo(o2.getFileName());
  102. }
  103. });
  104. //(6)遍历子目录子文件
  105. for(FileHeader fd : fileheaderList) {
  106. File f = new File(rootDir.getPath()+"\"+fd.getFileName());
  107. if(fd.isDirectory()) {
  108. //物理磁盘创建子目录
  109. f.mkdir();
  110. }else {
  111. //物理磁盘创建子文件
  112. f.createNewFile();
  113. //获取压缩包中子文件输入流
  114. InputStream in = archive.getInputStream(fd);
  115. //复制文件输入流至子文件
  116. FileUtils.copyInputStreamToFile(in, f);
  117. }
  118. }
  119. } catch (RarException | IOException e) {
  120. e.printStackTrace();
  121. }
  122. }
  123. }

4. Escenarios de uso

Lo anterior proporciona funciones de descompresión para archivos en dos formatos de compresión comunes (ZIP y RAR). Al juzgar el formato del archivo de entrada (según la extensión del archivo), llame al método de descompresión correspondiente (unzipounrar), puede descomprimir correctamente el contenido del archivo comprimido en el directorio especificado.

Esta característica es muy útil en muchos escenarios, como por ejemplo:

  1. Procesamiento y análisis de datos: cuando se obtienen datos en forma comprimida, es necesario descomprimirlos para obtener los datos originales para su procesamiento y análisis.
  2. Transferencia y almacenamiento de archivos: durante la transferencia o el almacenamiento de archivos, la compresión puede ahorrar espacio y mejorar la eficiencia de la transferencia, y luego descomprimirla para restaurar la estructura del archivo original después de llegar al destino.
  3. Desarrollo de software: durante el proceso de desarrollo, puede ser necesario procesar e integrar recursos de archivos comprimidos de diferentes fuentes.

En general, este código proporciona una forma flexible y reutilizable de manejar las operaciones de descompresión de archivos comprimidos ZIP y RAR, satisfaciendo las necesidades de procesamiento de archivos comprimidos en diversas aplicaciones.