Search

'Zip'에 해당되는 글 4건

  1. 2010.10.11 [zip] 압축하기3
  2. 2010.10.08 [zip] 압축하기2
  3. 2010.10.08 [zip] zip 압축하기/압축풀기
  4. 2010.09.28 [java] zip 파일 압축풀기

[zip] 압축하기3

프로그래밍/Java 2010. 10. 11. 16:39 Posted by galad
        // 압축 처리
        // 압축대상 폴더명을 압축에서 제외.
        // dirPath = /data/drm
        // zipPath = /data/drm/book
        // 압축 푼 디렉토리 = /data/drm/book
        // book 디렉토리를 대상으로 압축 시, 기본적으로는 book 디렉토리가 포함되어 압축되나
        // sourcePath를 한 depth 안쪽, 즉 zipPath로 지정하면 book 디렉토리를 제외한 상태로 압축된다.
        // (압축 시 압축대상 파일의 절대경로 - sourcePath의 경로)로 파일명 처리하므로, sourcePath를 조정하면 압축대상 디렉토리 제외 가능
        // 기존 압축파일 = book/내에 모든 파일. zipPath를 sourcePath로 하는 압축파일 = /모든 파일
//     zipEntry(dirPath, sourceFile, dirPath, zfileNm);
        zipEntry(zipPath, sourceFile, dirPath, zfileNm);


    /**
     * 압축 대상 파일이나 폴더를 압축 파일에 추가하여 압축한다.
     * 만일 넘겨 받은 파일이 폴더라면 하위 디렉토리 압축을 위해 재귀함수 호출로 처리한다.
     * @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 디렉토리도 생성됨.
                // sourcePath를 조절해서 압축대상 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();
                }
            }
        }
    }

    /**
     * 압축 대상 파일이나 폴더를 압축 파일에 추가하여 압축한다.
     * @param sourcePath 압축할 디렉토리 또는 파일이 위치한 경로. 즉 압축대상의 부모의 경로 / 예) D:\APIs\
     * @param sourceFile 압축할 디렉토리명 또는 이름 / 예) D:\APIs\ 내의 압축대상 j2sdk-1_4_2-doc
     * @param targetDir 압축한 zip 파일을 위치시킬 디렉토리 경로와 이름 / 예) D:\APIs
     * @param zipFileName zip파일명
     * @throws Exception
     */
    private static void zipEntry(String sourcePath,
                                    File sourceFile,
                                    String targetDir,
                                    String zipFileName) throws Exception {

        // java.util.zip.ZipOutputStream을 사용하면 압축시 한글 파일명은 깨지는 버그가 발생
        // 집출력 스트림에 집파일을 넣는다.
        ZipOutputStream zoutput = new ZipOutputStream((OutputStream) new FileOutputStream(new File(zipFileName)));

        zipEntry(sourcePath, sourceFile, targetDir, zoutput);

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


[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

[zip] zip 압축하기/압축풀기

프로그래밍/Java 2010. 10. 8. 15:36 Posted by galad
http://kwaknu.egloos.com/4989599
http://yeon97.egloos.com/1551569
http://sourceforge.net/projects/jazzlib/

아래 내용은 위의 伏地不動 님의 블로그에서 복사한 글입니다.
오직 저장의 목적으로만 사용함을 밝힙니다.

import system.log.Logger;
import system.exception.Exception;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


/**
 * Created by IntelliJ IDEA.
 * Date: 2006. 7. 6
 * Time: 오후 3:48:11
 * To change this template use File | Settings | File Templates.

 * java.util.zip에 있는 놈을 쓰게 되면 압축할 때 한글명으로 된 파일은 깨져서 들어간다..

 * 결국 그때문에 나중에 압축을 풀때 에러가 나게 된다...

 * 해서 이놈을 jazzlib 라이브러리를 사용하여 해결하였다....
 */

public class compressTest {
    static Logger logger = (Logger)Logger.getLogger();
    static final int COMPRESSION_LEVEL = 8;
    static final int BUFFER_SIZE = 64*1024;


    public static void main(String[] args) throws IOException {
        // 압축할 폴더를 설정한다.
        String targetDir = "D:\\test\\testest";
        // 현재 시간을 설정한다.
        long beginTime = System.currentTimeMillis();
        int cnt;
        byte[] buffer = new byte[BUFFER_SIZE];
        FileInputStream finput = null;
        FileOutputStream foutput;


        /*
         **********************************************************************************
         * java.util.zip.ZipOutputStream을 사용하면 압축시 한글 파일명은 깨지는 버그가

         * 발생합니다.
         * 이것은 나중에 그 압축 파일을 해제할 때 계속 한글 파일명이 깨는 에러가 됩니다.
         * 현재 Sun의 공식 입장은 이 버그를 향후 수정할 계획이 없다고 하며
         * 자체적으로 공식적 버그라고 인정하고 있지 않습니다.
         * 이런 비영어권의 설움...ㅠ.ㅠ
         * 해서 이 문제를 해결한 net.sf.jazzlib.ZipOutputStream을 추가하오니

         * 이 라이브러리 사용을 권장하는 바입니다.
         *********************************************************************************/
        net.sf.jazzlib.ZipOutputStream zoutput;


        /*
         ********************************************
         * 압축할 폴더명을 얻는다. : 절대 경로가 넘어올 경우 --> 상대경로로 변경한다...
         *********************************************/
        targetDir.replace('\\', File.separatorChar);
        targetDir.replace('/', File.separatorChar);
        String dirNm = targetDir.substring(targetDir.lastIndexOf(File.separatorChar)+1

                                                        , targetDir.length());

        // 압축할 폴더를 파일 객체로 생성한다.
        File file = new File(targetDir);
        String filePath = file.getAbsolutePath();
        logger.debug("File Path : " + file.getAbsolutePath());


        /*
         **************************************************************************
         * 폴더인지 파일인지 확인한다...
         * 만약 넘겨받은 인자가 파일이면 그 파일의 상위 디렉토리를 타겟으로 하여 압축한다.
         *****************************************************************************/
        if (file.isDirectory()) {
            logger.debug("Directory.........");
        } else {
            file = new File(file.getParent());
        }

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


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

        logger.debug("Zip File Path and Name : " + zfileNm);

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

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

        net.sf.jazzlib.ZipEntry zentry = null;


        try {
            for (int i=0; i < fileArray.length; i++) {
                // 압축할 파일 배열 중 하나를 꺼내서 입력 스트림에 넣는다.
                finput = new FileInputStream(fileArray[i]);

                // ze = new net.sf.jazzlib.ZipEntry ( inFile[i].getName());
                zentry = new net.sf.jazzlib.ZipEntry(fileArray[i].getName());

                logger.debug("Target File Name for Compression : "

                                    + fileArray[i].getName()

                                    + ", File Size : "

                                    + finput.available());

                zoutput.putNextEntry(zentry);


                /*
                 ****************************************************************
                 * 압축 레벨을 정하는것인데 9는 가장 높은 압축률을 나타냅니다.
                 * 그 대신 속도는 젤 느립니다. 디폴트는 8입니다.
                 *****************************************************************/
                zoutput.setLevel(COMPRESSION_LEVEL);

                cnt = 0;
                while ((cnt = finput.read(buffer)) != -1) {
                    zoutput.write(buffer, 0, cnt);
                }

                finput.close();
                zoutput.closeEntry();
            }
            zoutput.close();
            foutput.close();
        } catch (Exception e) {
            logger.fatal("Compression Error : " + e.toString());
            /*
             **********************************************
             * 압축이 실패했을 경우 압축 파일을 삭제한다.
             ***********************************************/
            logger.error(zfile.toString() + " : 압축이 실패하여 파일을 삭제합니다...");
            if (!zfile.delete()) {
                logger.error(zfile.toString() + " : 파일 삭제가 실패하여 다시 삭제합니다...");
                while(!zfile.delete()) {
                    logger.error(zfile.toString() + " : 삭제가 실패하여 다시 삭제합니다....");
                }
            }
            e.printStackTrace();
            throw new Exception(e);
        } finally {
            if (finput != null) {
                finput.close();
            }
            if (zoutput != null) {
                zoutput.close();
            }
            if (foutput != null) {
                foutput.close();
            }
        }

        long msec = System.currentTimeMillis() - beginTime;

        logger.debug("Check :: >> " + msec/1000 + "." + (msec % 1000) + " sec. elapsed...");
    }
}


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

[zip] 압축하기3  (0) 2010.10.11
[zip] 압축하기2  (0) 2010.10.08
[java] zip 파일 압축풀기  (0) 2010.09.28
[java] String, StringBuffer, StringBuilder  (0) 2010.09.28
[junit] 멀티스레드 테스트  (0) 2010.09.27

[java] zip 파일 압축풀기

프로그래밍/Java 2010. 9. 28. 20:07 Posted by galad
    /**
     * 넘겨받은 zip파일이 위치한 디렉토리에 zip 파일을 풀고, zip파일 내의 파일 목록(파일명)을 반환한다.
     * @param zipFilePath
     * @return zip파일에 들어있던 파일path 목록
     * @throws IOException
     */
    public static List<String> unzip(File file) throws IOException {

        List<String> fileList = new ArrayList<String>();

        // zip 파일 압축 해제
        ZipFile zipFile = new ZipFile(file,"EUC-KR");
        Enumeration entries = zipFile.getEntries();

        String zipFilePath = file.getPath();
        String orgDirPath = zipFilePath.substring(0, zipFilePath.lastIndexOf(File.separator));

        while(entries.hasMoreElements()) {

            ZipEntry zipEntry = (ZipEntry)entries.nextElement();
            String entryFileName = zipEntry.getName();

            System.out.println("File in Zip = " + entryFileName);

            if(zipEntry.isDirectory()) {
                (new File(orgDirPath + File.separator + entryFileName)).mkdir(); // 디렉토리 생성
                continue;
            }
            else {

                String[] tmpSplit = null; // 폴더 채로 압축하면, 폴더 내의 파일명은 [폴더명/폴더명/파일명] 이런 식으로 됨.

                try
                {
                    tmpSplit   = entryFileName.split(File.separator);
                }
                catch(Exception e)
                {
//                    tmpSplit = entryFileName.split("\\\\");
                    tmpSplit = entryFileName.split("/");
                }

                if(tmpSplit.length > 1)
                {
                    String tmpDir = "";
                    for(int j = 0; j < tmpSplit.length - 1; j++) // 파일이 여러 depth의 폴더 내에 있는 경우. 폴더/폴더/폴더/파일
                        tmpDir += (tmpSplit[j] + File.separator); // 상위의 모든 폴더명 붙이기

                    tmpDir = orgDirPath + File.separator + tmpDir; // zip 파일이 위치한 디렉토리에 압축된 디렉토리 생성

                    File tmpFile = new File(tmpDir);
                    if(!tmpFile.exists())
                        tmpFile.mkdir();
                }

                // 대상 파일
                String targetFilePath = orgDirPath + File.separator + entryFileName;

                // 파일 복사
                copyInputStream(zipFile.getInputStream(zipEntry), new BufferedOutputStream(new FileOutputStream(targetFilePath)));
//                System.out.println("FILE [" + entryFileName + "] COPIED TO " + orgDirPath);

                fileList.add(entryFileName);
            }
        }

        if(zipFile != null) // 열은 zip 파일 닫기
            zipFile.close();

        return fileList;
    }

    /**
     * 파일을 stream으로 읽어들여 대상 outputStream에 복사하는 메소드
     * @param in
     * @param out
     * @throws IOException
     */
    private static final void copyInputStream(InputStream in, OutputStream out) throws IOException
    {
        byte[] buffer = new byte[1024];
        int len;

        while ((len = in.read(buffer)) >= 0)
            out.write(buffer, 0, len);

        in.close();
        out.close();
    }


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

[zip] 압축하기2  (0) 2010.10.08
[zip] zip 압축하기/압축풀기  (0) 2010.10.08
[java] String, StringBuffer, StringBuilder  (0) 2010.09.28
[junit] 멀티스레드 테스트  (0) 2010.09.27
[jar] jar 압축하기/해제하기  (0) 2010.09.10