#java/code - Java 압축하기, 압축풀기 ZipEntry, FileUtils, StringUtils
본문 바로가기
Programming/Java Code

#java/code - Java 압축하기, 압축풀기 ZipEntry, FileUtils, StringUtils

by 권가 2019. 5. 14.

압축을 해달라는 문의가 들어와 이곳저곳 찾아보니 잘 정리된 http://egloos.zum.com/yeon97/v/1551569 님 문서를 참고했습니다~

 

압축할 디렉터리 정보

Console

압축 후

압축 레벨 별 용량 크기

Console

압축 풀기 후

level3: toLowerCase(true)

level7: toLowerCase(false)

 

package zipTest;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Scanner;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;


public class ZipUtils {
	
	private static final String ABSOLUTEPATH = "D:\\ziptest\\";

    private static final int BUFFER_SIZE = 1024 * 2;

    /**
     * 지정된 폴더/파일을 .zip 파일로 압축한다.
     * @param sourcePath - 압축 대상 디렉토리
     * @param output - 저장 zip 파일 이름
     * @throws Exception
     */
    public static void zip(String sourcePath, String output, int level) throws Exception {

        // 압축 대상(sourcePath)이 디렉토리나 파일이 아니면 리턴한다.
        File sourceFile = new File(sourcePath);
        if (!sourceFile.isFile() && !sourceFile.isDirectory()) {
            throw new Exception("압축 대상의 파일을 찾을 수가 없습니다.");
        }

        // output 의 확장자가 zip이 아니면 리턴한다.
        if (!(StringUtils.substringAfterLast(output, ".")).equalsIgnoreCase("zip")) {
            throw new Exception("압축할 파일명의 확장자를 .zip으로 설정");
        }

        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        ZipOutputStream zos = null;

        try {
            fos = new FileOutputStream(output);
            bos = new BufferedOutputStream(fos);
            zos = new ZipOutputStream(bos);
            zos.setLevel(level);
//			Zip 파일 생성
            zipEntry(sourceFile, sourcePath, zos);
            zos.finish();
        } finally {
            if (zos != null) {
                zos.close();
            }
            if (bos != null) {
                bos.close();
            }
            if (fos != null) {
                fos.close();
            }
        }
    }

    /**
     * 압축
     * @param sourceFile
     * @param sourcePath
     * @param zos
     * @throws Exception
     */
    private static void zipEntry(File sourceFile, String sourcePath, ZipOutputStream zos) throws Exception {
        // 압축할 대상이 디렉터리인 경우 하위 파일, 디렉터리 리스트 가져옴
        if (sourceFile.isDirectory()) {
            if (sourceFile.getName().equalsIgnoreCase(".metadata")) { // .metadata 디렉토리 return
                return;
            }
//          File형 배열 fileArray에 대상의 하위 파일, 디렉터리 리스트 가져옴
            File[] fileArray = sourceFile.listFiles();
            for (int i = 0; i < fileArray.length; i++) {
                zipEntry(fileArray[i], sourcePath, zos); // 재귀 호출
            }
        } else { // 압축할 대상이 디렉터리가 아닐 때,
            BufferedInputStream bis = null;
            try {
                String sFilePath = sourceFile.getPath();
                String zipEntryName = sFilePath.substring(sourcePath.length(), sFilePath.length());

                bis = new BufferedInputStream(new FileInputStream(sourceFile));
                ZipEntry zentry = new ZipEntry(zipEntryName);
                zentry.setTime(sourceFile.lastModified());
                zos.putNextEntry(zentry);

                byte[] buffer = new byte[BUFFER_SIZE];
                int cnt = 0;
                while ((cnt = bis.read(buffer, 0, BUFFER_SIZE)) != -1) {
                    zos.write(buffer, 0, cnt);
                }
                zos.closeEntry();
            } finally {
                if (bis != null) {
                    bis.close();
                }
            }
        }
    }

    /**
     * Zip 파일의 압축을 푼다.
     *
     * @param string - 압축 풀 Zip 파일
     * @param absolutepath2 - 압축 푼 파일이 들어간 디렉토리
     * @param fileNameToLowerCase - 파일명을 소문자로 바꿀지 여부(true, false)
     * @throws Exception
     */
    public static void unzip(String string, String absolutepath2, boolean fileNameToLowerCase) throws Exception {
        FileInputStream fis = null;
        ZipInputStream zis = null;
        ZipEntry zentry = null;

        try {
            fis = new FileInputStream(string);
            zis = new ZipInputStream(fis);

            while ((zentry = zis.getNextEntry()) != null) {
                String fileNameToUnzip = zentry.getName();
                if (fileNameToLowerCase) { // fileName toLowerCase
                    fileNameToUnzip = fileNameToUnzip.toLowerCase();
                }

                File targetFile = new File(absolutepath2, fileNameToUnzip);

                if (zentry.isDirectory()) {// Directory 인 경우
                	FileUtils.forceMkdir(targetFile);
                } else { // File 인 경우 parent Directory 생성
                	FileUtils.forceMkdir(targetFile.getParentFile());
                    unzipEntry(zis, targetFile);
                }
            }
        } finally {
            if (zis != null) {
                zis.close();
            }
            if (fis != null) {
                fis.close();
            }
        }
    }

    /**
     * Zip 파일의 한 개 엔트리의 압축을 푼다.
     *
     * @param zis - Zip Input Stream
     * @param filePath - 압축 풀린 파일의 경로
     * @return
     * @throws Exception
     */
    protected static File unzipEntry(ZipInputStream zis, File targetFile) throws Exception {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(targetFile);

            byte[] buffer = new byte[BUFFER_SIZE];
            int len = 0;
            while ((len = zis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
        } finally {
            if (fos != null) {
                fos.close();
            }
        }
        return targetFile;
    }
    
    static Scanner scan = new Scanner(System.in);
    
    public static void main(String[] args) throws Exception { 
    	int menu, level;
    	String conString = null;
    	while(true) {
    		System.out.println("1: 압축하기 2: 압축풀기");
    		menu = scan.nextInt();
    		if(menu == 1) {  
    			System.out.print("압축된 파일의 이름을 지정해주세요.?\n"+ABSOLUTEPATH+"\\");
    			conString = scan.next();
    			System.out.print(ABSOLUTEPATH + "\\"+ conString + ".zip을 몇 Level로 압축하시겠습니까? >>(1~9) ");
    			level = scan.nextInt();
    			if(!(1<=level&&level<=9)) {
    				System.out.println("잘못된 Level 설정 처음부터 시작");
    				continue;
    			}
		    	ZipUtils.zip(ABSOLUTEPATH + "\\folder", ABSOLUTEPATH+"\\"+conString+".zip", level);
		    	System.out.println(ABSOLUTEPATH + "\\"+ conString + ".zip이 Level" + level +"으로 압축 되었습니다.\n------------------------------");
    		}
    		else if(menu == 2) {
    			System.out.println("압출풀 파일의 이름을 지정해주세요.?");
    			conString = scan.next();
//				3번 째 인자에 true(소문자로 바꾸기), false(소문자로 안바꾸기)
		    	ZipUtils.unzip(ABSOLUTEPATH+"\\"+conString+".zip", ABSOLUTEPATH+"\\"+conString, false);
		    	System.out.println("압축 풀기 끝");
    		}
    		else break;
    	}
    	System.out.println("시스템 종료...");
    }
}

댓글