기술나눔

Java를 통해 zip 파일과 rar 파일의 압축을 푸는 방법은 무엇입니까?

2024-07-12

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

목차

1. 사용된 지식 포인트

2. 코드 표시(분해 버전)

3. 코드 표시(전체 버전)


1. 사용된 지식 포인트

1.IO 스트림:

입력: 입력, "입력 스트림"을 통해 파일 읽기

출력: 출력, "출력 스트림"을 통해 파일 쓰기

2. 파일 작업 관련:

파일 클래스: 파일 및 디렉터리의 경로를 나타내는 데 사용됩니다.

FileInputStream 및 FileOutputStream: 파일을 읽고 쓰는 데 사용됩니다.

3. 압축 파일 처리:

ZipInputStream: ZIP 압축 파일을 읽기 위한 입력 스트림입니다.

ZipEntry: ZIP 압축 파일의 항목(파일 또는 디렉터리)을 나타냅니다.

4.예외 처리:

FileNotFoundException: 존재하지 않는 파일에 액세스하려고 할 때 발생합니다.

IOException: 입력 및 출력 작업의 일반적인 예외를 처리하는 데 사용됩니다.

RarException: RAR 아카이브 작업과 관련된 특정 예외를 처리합니다.

5. 데이터 입력 및 출력 스트림:

InputStream: 데이터를 읽기 위한 입력 스트림입니다.

6. 수집 작업:

목록: 파일 헤더 정보를 저장하는 데 사용되는 목록입니다.

7. 비교기:파일 헤더 목록을 정렬하는 데 사용됩니다.

8. 타사 라이브러리 commons-io의 FileUtils 클래스:(이 jar 패키지는 기사 마지막 부분에 있습니다.)

디렉터리를 삭제하고 입력 스트림을 파일에 복사하는 데 사용됩니다.

2. 코드 표시(분해 버전)

1단계: 파일 형식 결정

  • ".zip" 파일인 경우 unzip() 메서드를 호출하여 ZIP 파일의 압축을 푼다. ".rar" 파일인 경우 unrar() 메서드를 호출하여 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. }

2단계: unzip() 메서드 정의

  • 입력 파일 경로를 기반으로 소스 파일 객체를 생성합니다.
  • 압축이 풀린 루트 디렉터리 경로를 결정하고 해당 파일 개체를 만듭니다.
  • 루트 디렉터리가 이미 존재하는 경우 삭제해 보십시오(사용 포함).FileUtils유틸리티 클래스는 비어 있지 않은 디렉터리를 삭제한 다음 루트 디렉터리를 다시 만듭니다.
  • ZIP 형식을 읽기 위한 입력 스트림을 만듭니다.
  • 아카이브의 각 항목(하위 파일 또는 하위 디렉토리)을 반복합니다.
  • 각 항목에 해당하는 파일 객체를 만듭니다.
  • 항목이 하위 파일인지 하위 디렉터리인지 확인하고 각각 파일이나 디렉터리를 만듭니다.
  • 서브파일의 경우 출력 스트림을 생성하고, 입력 스트림에서 데이터를 읽고, 서브파일에 씁니다.
  • 찾을 수 없는 파일을 처리하고 예외를 입력 및 출력합니다.
  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. }

3단계: unrar() 메서드 정의

  • 입력된 RAR 파일 경로를 기반으로 루트 디렉터리의 파일 객체를 생성합니다.
  • 루트 디렉터리가 존재하는지 확인하고, 존재한다면 삭제해 보세요.FileUtils가능한 예외를 처리한 후) 루트 디렉터리를 만듭니다.
  • RAR 압축 파일을 읽기 위한 파일 생성Archive물체.
  • 압축 파일의 모든 하위 디렉터리와 하위 파일 가져오기FileHeader객체를 생성하고 목록에 저장합니다.
  • 하위 디렉터리 및 하위 파일 이름을 기준으로 목록을 정렬합니다.
  • 목록의 각 항목을 반복합니다.FileHeader물체.
  • ~에 따르면FileHeaderObject는 해당 파일 객체를 생성합니다.
  • 하위 디렉터리인지 하위 파일인지 확인하고 각각 디렉터리나 파일을 만듭니다.
  • 하위 파일의 경우 입력 스트림을 가져와서 사용하세요.FileUtils입력 스트림을 서브파일에 복사합니다.
  • 가능한 RAR 관련 예외와 입력 및 출력 예외를 처리합니다.
  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. 코드 표시(전체 버전)

  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. 사용 시나리오

위의 내용은 두 가지 일반적인 압축 형식(ZIP 및 RAR)의 파일에 대한 압축 해제 기능을 제공합니다. (파일 확장자에 따라) 입력 파일의 형식을 판단하여 해당 압축 해제 방법을 호출합니다(unzip또는unrar), 압축 파일의 내용을 지정된 디렉터리에 올바르게 압축 해제할 수 있습니다.

이 기능은 다음과 같은 다양한 시나리오에서 매우 유용합니다.

  1. 데이터 처리 및 분석: 압축된 형태의 데이터를 얻은 경우 처리 및 분석을 위한 원본 데이터를 얻기 위해 압축을 풀어야 합니다.
  2. 파일 전송 및 저장: 파일 전송 또는 저장 중에 압축을 하면 공간을 절약하고 전송 효율성을 높일 수 있으며, 대상에 도달한 후 압축을 풀어 원래 파일 구조를 복원할 수 있습니다.
  3. 소프트웨어 개발: 개발 프로세스 중에는 다양한 소스의 압축 파일 리소스를 처리하고 통합해야 할 수도 있습니다.

전반적으로 이 코드는 ZIP 및 RAR 압축 파일의 압축 해제 작업을 처리하는 유연하고 재사용 가능한 방법을 제공하여 다양한 응용 프로그램에서 압축 파일을 처리하는 요구 사항을 충족합니다.