[zip] 압축하기2

프로그래밍/Java 2010. 10. 8. 17:34 Posted by galad
아래 내용으로는 뭔가 부족해서 검색중에 발견. http://tjsoftware.tistory.com/6
훨씬 깔끔하고 좋다...

다만 주석 내용이 소스랑 다른 부분이 있어서 그 부분 주석 수정 및 기타 주석을 추가했음.
zipEntry() 이외는 직접 작성.

        // 폴더 안에 있는 파일들을 파일 배열 객체로 가져온다.
        File[] fileArray = sourceFile.listFiles();

        // 압축할 파일 이름
        String zfileNm = filePath + ".zip";
        int num = 1;
        while (new File(zfileNm).exists()) { // 압축할 파일 명이 존재한다면 다른 이름으로 파일명을 생성
            zfileNm = filePath + "_" + num++ + ".zip";
        }
        System.out.println("Zip File Path and Name : " + zfileNm);

        // Zip 파일을 만든다.
        File zfile = new File(zfileNm);

        // Zip 파일 객체를 출력 스트림에 넣는다.
        foutput = new FileOutputStream(zfile);

        // 집출력 스트림에 집파일을 넣는다.
        zoutput = new ZipOutputStream((OutputStream)foutput);

        long beginTime = System.currentTimeMillis();

        // 실제 압축 처리
        zipEntry(dirPath, sourceFile, dirPath, zoutput);

        if (zoutput != null) {
            zoutput.close();
        }
        if (foutput != null) {
            foutput.close();
        }

        long msec = System.currentTimeMillis() - beginTime;

        System.out.println("Check :: >> " + msec/1000 + "." + (msec % 1000) + " sec. elapsed...");

    /**
     * 압축 대상 파일이나 폴더를 압축 파일에 추가하여 압축한다.
     * 만일 넘겨 받은 파일이 폴더라면 하위 디렉토리 압축을 위해 재귀함수 호출로 처리한다.
     * @param sourcePath 압축할 디렉토리/파일의 경로 / 예) D:\APIs\
     * @param sourceFile 압축할 디렉토리 경로와 이름 / 예) D:\APIs\ 내의 압축대상 j2sdk-1_4_2-doc
     * @param targetDir 압축한 zip 파일을 위치시킬 디렉토리 경로와 이름 / 예) D:\APIs
     * @param zipOutputStream Zip출력스트림 - 압축할 zip 파일에 대한 zip출력스트림. / 예) D:\APIs\zipModuleTest.zip
     * @throws Exception
     */
    private static void zipEntry(String sourcePath,
                                File sourceFile,
                                String targetDir,
                                ZipOutputStream zipOutputStream) throws Exception{

        // 만일 디렉토리명이 .metadata라면 처리하지 않고 skip한다.
        if (sourceFile.isDirectory()) {
            if(sourceFile.getName().equalsIgnoreCase(".metadata")) {
                return;
            }

            File[] fileArray = sourceFile.listFiles();
            for(int i = 0; i < fileArray.length; i++) { // 디렉토리면 디렉토리 내 파일 목록을 가지고 재귀호출
                zipEntry(sourcePath, fileArray[i], targetDir,zipOutputStream);
            }
        } else {
            BufferedInputStream inputStream = null;
            byte[] buffer = new byte[BUFFER_SIZE];
            try {
                if (sourceFile.getAbsolutePath().equalsIgnoreCase(targetDir)) {
                    return;
                }

                String strAbsPath = sourceFile.getPath(); // 압축대상 파일의 절대경로

                // 압축대상 파일의 절대경로에서 원본경로를 제외한 경로를 추출
                // ex) /test/test.xml 에서 test.xml을 압축하면 sourcePath = /test/, 압축대상의 절대경로는 /test/test.xml 이므로
                // zipEntryName은 test.xml 이 된다.
                // ex2) 만약 디렉토리 내의 파일을 압축하면(디렉토리도 압축에 포함됨), /test/dir/test.xml 에서 dir 을 압축하면
                // sourePath = /test/, 압축대상의 절대경로는 /test/dir/test.xml 이므로 zipEntryName은 dir/test.xml 이 된다.
                // 이 상태로 압축하면 압축파일 내에 dir 디렉토리도 생성됨.
                String strZipEntryName = strAbsPath.substring(sourcePath.length() + 1, strAbsPath.length());

                inputStream = new BufferedInputStream(new FileInputStream(sourceFile));
                ZipEntry zentry = new ZipEntry(strZipEntryName);
                zentry.setTime(sourceFile.lastModified());
                zipOutputStream.putNextEntry(zentry);

                int cnt =0;
                while ( (cnt = inputStream.read(buffer, 0, BUFFER_SIZE)) != -1) {
                    zipOutputStream.write(buffer, 0, cnt);
                }

                zipOutputStream.closeEntry();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            finally {
                if (inputStream != null) {
                    inputStream.close();
                }
            }
        }
    }

체크 포인트
1. ZipEntry 생성 시 디렉토리명/파일명 으로 생성하면, 압축 시 디렉토리도 같이 생성됨.
2. zipEntry(dirPath, sourceFile, dirPath, zoutput)
 
- dirPath : 압축 대상(디렉토리/파일)의 부모 디렉토리의 경로
 - sourceFile : 압축 대상 디렉토리 혹은 파일. File class
 - targetDir : 압축된 zip 파일이 위치할 디렉토리 경로. 특별히 필요는 없는 듯
 - zipoutput : 실제 압축될 zip 파일. ZipOutputStream class.
> 예를 들어, c:\test\test\test.xml 이 있고 c:\test\test 를 c:\test\test.zip 으로 압축한다고 하면
 dirPath = c:\test\
 sourceFile = new File(c:\test\).listFiles() 
 targetDir = c:\test\
 zipoutput = new ZipOutputStream((OutputStream)new FileOutputStream(c:\test\test.zip))
3. stream close 하는 것 까먹지 말 것. zip 파일을 못 열게됨.

'프로그래밍 > Java' 카테고리의 다른 글

[java/펌] Java Character Set의 이해  (0) 2010.11.11
[zip] 압축하기3  (0) 2010.10.11
[zip] zip 압축하기/압축풀기  (0) 2010.10.08
[java] zip 파일 압축풀기  (0) 2010.09.28
[java] String, StringBuffer, StringBuilder  (0) 2010.09.28