Condivisione della tecnologia

Come decomprimere file zip e file rar tramite Java?

2024-07-12

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

Sommario

1. Punti conoscenza utilizzati

2. Visualizzazione codici (versione scomposta)

3. Visualizzazione del codice (versione complessiva)


1. Punti conoscenza utilizzati

Flusso 1.IO:

Input: input, leggi i file attraverso il "flusso di input"

Output: output, scrive file attraverso il "flusso di output"

2. Operazioni sui file correlate:

Classe file: utilizzata per rappresentare percorsi di file e directory.

FileInputStream e FileOutputStream: utilizzati per leggere e scrivere file.

3. Elaborazione di file compressi:

ZipInputStream: flusso di input per la lettura di file compressi ZIP.

ZipEntry: rappresenta una voce (file o directory) in un file compresso ZIP.

4.Gestione delle eccezioni:

FileNotFoundException: generato quando si tenta di accedere a un file che non esiste.

IOException: utilizzato per gestire eccezioni generali nelle operazioni di input e output.

RarException: gestisce eccezioni specifiche relative alle operazioni di archivio RAR.

5. Flussi di input e output di dati:

InputStream: flusso di input per la lettura dei dati.

6. Operazioni di incasso:

Elenco: un elenco utilizzato per memorizzare le informazioni sull'intestazione del file.

7. Comparatore:Utilizzato per ordinare l'elenco delle intestazioni dei file.

8. Classe FileUtils nella libreria di terze parti commons-io:(Questo pacchetto barattolo è alla fine dell'articolo)

Utilizzato per eliminare directory e copiare flussi di input su file.

2. Visualizzazione codici (versione scomposta)

Passaggio 1: determinare il tipo di file

  • Se è un file ".zip", chiama il metodo unzip() per decomprimere il file ZIP. Se è un file ".rar", chiama il metodo unrar() per decomprimere il file 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. }

Passaggio 2: definire il metodo unzip()

  • Crea un oggetto file di origine in base al percorso del file di input.
  • Determinare il percorso della directory root decompressa e creare l'oggetto file corrispondente.
  • Se la directory root esiste già, prova a eliminarla (incluso l'utilizzoFileUtilsLa classe di utilità elimina le directory non vuote) e quindi ricrea la directory principale.
  • Crea un flusso di input per leggere il formato ZIP.
  • Scorrere ogni voce (sottofile o sottodirectory) nell'archivio.
  • Crea un oggetto file corrispondente per ogni voce.
  • Determinare se la voce è un sottofile o una sottodirectory e creare rispettivamente il file o la directory.
  • Per i file secondari, crea un flusso di output, leggi i dati dal flusso di input e scrivi nel file secondario.
  • Gestire possibili file non trovati ed eccezioni di input e output.
  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. }

Passaggio 3: definire il metodo unrar()

  • Crea un oggetto file della directory principale in base al percorso del file RAR di input.
  • Determina se la directory root esiste e, se esiste, prova a eliminarla (usaFileUtilsgestire possibili eccezioni) e quindi creare la directory root.
  • Crea un file per leggere file compressi RARArchiveoggetto.
  • Ottieni tutte le sottodirectory e i sottofile in un file compressoFileHeaderoggetto e memorizzato nell'elenco.
  • Ordina l'elenco in base ai nomi di sottodirectory e sottofile.
  • Itera su ogni elemento dell'elencoFileHeaderoggetto.
  • secondoFileHeaderObject crea l'oggetto file corrispondente.
  • Determina se si tratta di una sottodirectory o di un sottofile e crea rispettivamente la directory o il file.
  • Per i file secondari, ottieni il flusso di input e usaFileUtilsCopia il flusso di input in un file secondario.
  • Gestire possibili eccezioni relative a RAR ed eccezioni di input e output.
  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. Visualizzazione del codice (versione complessiva)

  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. Scenari di utilizzo

Quanto sopra fornisce funzioni di decompressione per i file in due formati di compressione comuni (ZIP e RAR). A giudicare dal formato del file di input (in base all'estensione del file), chiamare il metodo di decompressione corrispondente (unzipOunrar), può decomprimere correttamente il contenuto del file compresso nella directory specificata.

Questa funzionalità è molto utile in molti scenari, ad esempio:

  1. Elaborazione e analisi dei dati: quando si ottengono dati in forma compressa, è necessario decomprimerli per ottenere i dati originali per l'elaborazione e l'analisi.
  2. Trasferimento e archiviazione di file: durante il trasferimento o l'archiviazione di file, la compressione può risparmiare spazio e migliorare l'efficienza del trasferimento, quindi decomprimere per ripristinare la struttura originale del file una volta raggiunta la destinazione.
  3. Sviluppo software: durante il processo di sviluppo potrebbe essere necessario elaborare e integrare risorse di file compressi provenienti da diverse fonti.

Nel complesso, questo codice fornisce un modo flessibile e riutilizzabile per gestire le operazioni di decompressione dei file compressi ZIP e RAR, soddisfacendo le esigenze di elaborazione dei file compressi in varie applicazioni.