[Java] Zip 압축하기


Development note/Java  2015. 6. 8. 22:34

안녕하세요. 명월입니다.


이번 포스트에 Zip파일로 압축하는 방법을 공부하겠습니다.


Java로 Zip파일 압축 모듈은 Java의 API에 포함되어 있는 내용이고 그렇게 어려운 내용도 아닙니다만, 만들어진 소스를 구하려고 구글링을 하면 각기 제시하는 예제도 다 틀리고 버그도 많이 있어서 제가 만들어 봤습니다.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class Zip {
  /**
   * 압축 메소드
   * @param path 경로
   * @param outputFileName 출력파일명
   */
  public static void compress(String path,String outputFileName) throws Throwable{
    File file = new File(path);
    int pos = outputFileName.lastIndexOf(".");
    if(!outputFileName.substring(pos).equalsIgnoreCase(".zip")){
      outputFileName += ".zip";
    }
    // 압축 경로 체크
    if(!file.exists()){
      throw new Exception("Not File!");
    }
    // 출력 스트림
    FileOutputStream fos = null;
    // 압축 스트림
    ZipOutputStream zos = null;
    try{
      fos = new FileOutputStream(new File(outputFileName));
      zos = new ZipOutputStream(fos);
      // 디렉토리 검색
      searchDirectory(file,zos);      
    }catch(Throwable e){
      throw e;
    }finally{
      if(zos != null) zos.close();
      if(fos != null) fos.close();
    }
  }
  /**
   * 다형성 
   */
  private static void searchDirectory(File file, ZipOutputStream zos) throws Throwable{
    searchDirectory(file,file.getPath(),zos);
  }
  /**
   * 디렉토리 탐색
   * @param file 현재 파일
   * @param root 루트 경로
   * @param zos 압축 스트림
   */
  private static void searchDirectory(File file,String root,ZipOutputStream zos) 
      throws Exception{
    //지정된 파일이 디렉토리인지 파일인지 검색
    if(file.isDirectory()){
      //디렉토리일 경우 재탐색(재귀)
      File[] files = file.listFiles();
      for(File f : files){
        searchDirectory(f,root,zos);
      }
    }else{
      //파일일 경우 압축을 한다.
      compressZip(file,root,zos);
    }
  }
  /**
   * 압축 메소드
   * @param file
   * @param root
   * @param zos
   * @throws Exception
   */
  private static void compressZip(File file, String root, ZipOutputStream zos) throws Exception{
    FileInputStream fis = null;
    try{
      String zipName = file.getPath().replace(root+"\\", "");
      // 파일을 읽어드림
      fis = new FileInputStream(file);
      // Zip엔트리 생성(한글 깨짐 버그)
      ZipEntry zipentry = new ZipEntry(zipName);
      // 스트림에 밀어넣기(자동 오픈)
      zos.putNextEntry(zipentry);
      int length = (int)file.length();
      byte[] buffer = new byte[length];
      //스트림 읽어드리기
      fis.read(buffer, 0, length);
      //스트림 작성
      zos.write(buffer, 0, length);
      //스트림 닫기
      zos.closeEntry();
      
    }catch(Throwable e){
      throw e;
    }finally{
      if(fis != null) fis.close();
    }
  }
  public static void main(String[] args){
    try{
      Zip.compress("d:\\test", "d:\\test.zip");
    }catch(Throwable e){
      e.printStackTrace();
    }
  }
}

소스는 크게 압축하는 스트림 선언 메소드, 경로탐색, 압축으로 나눕니다.

먼저 IO를 사용할 스트림을 두개 선언을 하고 압축 경로를 경로 탐색 메소드로 넘깁니다.

그리고 디렉토리일 경우 재탐색으로 재귀를 하고 파일일 경우 스트림을 넘겨서 압축을 합니다.


실행을 한 결과화면입니다.

압축 실행결과