[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
참고: http://cacky.tistory.com/36
http://iolothebard.tistory.com/291

일단, StringBuffer랑 StringBuilder

StringBuffer와 StringBuilder의 유일한 차이점은, StringBuffer가 동기화(synchronized)되고, StringBuilder는 동기화되지 않는(unsynchronized) 란다.
따라서, 프로그램이 단일 쓰레드 환경(single thread)에서 동작해야 한다면 StringBuilder를 쓰는 것이 StringBuffer보다 더 효율적(efficient)이다.

자세한 것은 링크 참조...

[junit] 멀티스레드 테스트

프로그래밍/Java 2010. 9. 27. 11:40 Posted by galad
참조: http://devyongsik.tistory.com/263
http://today.java.net/pub/a/today/2003/08/06/multithreadedTests.html

보통은 스레드가 다 돌기 전에 junit 테스트가 끝나버림.
groboutils 이라는 라이브러리 사용해서 멀티스레드 테스트 가능.

public class Tester extends TestRunnable { //net.sourceforge.groboutils.junit.v1.TestRunnable를 상속 
    private Log logger = LogFactory.getLog(Tester.class); 
 
    int i = 0; 
 
    public Tester(int i ) { 
        this.i = i; 
    } 
 
    @Override 
    public void runTest() { //net.sourceforge.groboutils.junit.v1.TestRunnable의 runTest메서드를 오버라이드 
                //이 메서드는 Runnable의 run 메서드가 해야 할 일이 들어갑니다. 
        try { 
            Thread.sleep(1000); 
        } catch (InterruptedException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        } 
 
        System.out.println(Thread.currentThread().getName() + " : [" + i + "]"); 
    } 


public class TestThread extends TestCase { 
    private Log logger = LogFactory.getLog(TestThread.class); 
 
    @Test 
    public void testM() throws Throwable { 
        TestRunnable[] t = new TestRunnable[20]; //TestRunnable로 배열을 만들고 
 
        for(int index = 0; index < 20; index++) { 
            t[index] = new Tester(index); //TestRunnable을 상속한 Runnable의 run 메서드를 테스트 할 클래스를 넣습니다. 
        } 
 
        MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(t); //이렇게 생성하고 
        mttr.runTestRunnables(); //이렇게 테스트 합니다. 
 
        System.out.println("main end........................."); 
    } 


위와 같이 하면 된다는데, 길고 복잡해서 그냥 스레드 돌리고 밑에다가 sleep 줘버렸음 ㅡ.ㅡ;;;

[oracle] SELECT 를 사용한 UPDATE 3

프로그래밍/DB 2010. 9. 14. 14:42 Posted by galad
UPDATE /*+ bypass_ujvc */
(
    SELECT
        CONTENT_ID,
        HDV_YN,
        META18 AS META_HDV_YN
    FROM
    (
        SELECT
            A.CONTENT_ID
            ,CASE
                WHEN COUNT(B.META02) > 0 THEN 'Y'
                ELSE 'N'
            END AS HDV_YN
            ,C.META18
        FROM
            SUB_CONTENT_META A, SUB_CONTENT_META_EXTEND B, CONTENT_META_EXTEND C
        WHERE
            A.SUB_CONTENT_ID = B.SUB_CONTENT_ID
            AND A.CONTENT_ID = C.CONTENT_ID
            AND B.META02 = 'PD009703'
    --        AND    A.CONTENT_ID = ''
        GROUP BY
            A.CONTENT_ID, C.META18
    )
)
SET META_HDV_YN = HDV_YN

CONTENT_META_EXTEND 의 컬럼을 업데이트하고 싶은데 위와 같이 안쪽(?)에서 뷰를 만들 때 같이 조인해버리면
"가상 열은 사용할 수 없습니다" 라는 에러가 난다.

아래처럼 실제 데이터 넣을 컬럼은 가장 외부로 뺄 것
참고: http://database.sarang.net/?inc=read&aid=35544&criteria=oracle&subcrit=&id=36136&limit=20&keyword=&page=50

[가상 Table에 정보를 저장(Insert) 하거나 변경(update)를 수행할 수 없지요

즉, UPDATE (SELECT....)

SELECT 부분이 실 Table이어야만 하지 Select된 결과에 대한 것은 변경이나 저장을

할 수 없는 것이지요.

따라서 Select 부분을 조건절로 보내고, 실 Table을 정의하시면 됩니다.]


UPDATE /*+ bypass_ujvc */
(
    SELECT
        T.CONTENT_ID,
        T.HDV_YN,
        C.META18 AS META_HDV_YN
    FROM
    (
        SELECT
            A.CONTENT_ID
            ,CASE
                WHEN COUNT(B.META02) > 0 THEN 'Y'
                ELSE 'N'
            END AS HDV_YN
        FROM
            SUB_CONTENT_META A, SUB_CONTENT_META_EXTEND B
        WHERE
            A.SUB_CONTENT_ID = B.SUB_CONTENT_ID
            AND B.META02 = 'PD009703'
            AND    A.CONTENT_ID = '0000024061'
        GROUP BY
            A.CONTENT_ID
    ) T, CONTENT_META_EXTEND C
    WHERE
        T.CONTENT_ID = C.CONTENT_ID
)
SET META_HDV_YN = HDV_YN;


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

[oracle] Windows 7 과 oracle, Toad  (0) 2011.03.09
[Tool] 토드 폰트 변경하기  (0) 2010.11.19
[oracle] select 문을 이용한 update 2  (0) 2010.08.16
[SQLite] Command Line Shell For SQLite  (0) 2010.05.24
[SQLite] Quick Start  (1) 2010.05.24

[jar] jar 압축하기/해제하기

프로그래밍/Java 2010. 9. 10. 16:40 Posted by galad
- JAR 파일 만들기
   jar cvf 만들파일명.jar *.*


- JAR 파일 업데이트
   jar uvf 만들파일명.jar *.*


- JAR 파일 풀기
   jar xvf 압축풀파일명.jar *.*
참고: http://www.yunsobi.com/tt/subby/99
참고: http://decoder.tistory.com/37

첨부된 파일은 검색에서 나온 것으로 문제 있으면 삭제하겠습니다.

package com.omp.bp.cms.batchreg.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;

import com.omp.bp.cms.batchreg.BatchRegisterErrorConstants;
import com.omp.bp.cms.util.DateUtil;

/**
 * 배치 등록 관련 에러 로그 처리 클래스. 콘텐츠 하나에 대한 에러로그XML 생성.
 * @author Sung,HongJe
 *
 */
public class BatchRegisterError {

    private final static Logger log = Logger.getLogger(BatchRegisterError.class);

    private final String ERROR_FILE_NAME_HEADER = "ERROR_";
    private final String ERROR_FILE_EXT = "XML";

    /**
     * 에러 로그 파일 생성
     * @param ftpRepoPath ftp 디렉토리 패스
     * @param contentId 콘텐츠ID
     * @param contentType 콘텐츠타입 - C:채널, E:콘텐츠(에피소드)
     * @param errorCode 에러코드
     * @throws IOException
     */
    public void makeErrorLog(String ftpRepoPath, String contentId, String contentType, int errorCode) throws IOException {

        // 1. ERROR 파일패스 설정 : ftpRepo/ERROR_[TYPE]_[CID].XML
        // 2. 에러 코드를 이용해서 XML 내용 설정
        // 3. 파일로 저장

        // ftpRepo/ERROR_C_000050151.XML
        String filePath = ftpRepoPath + File.separator + ERROR_FILE_NAME_HEADER + contentType.toUpperCase() + "_" + contentId + "." + ERROR_FILE_EXT;
        String errorMsg = BatchRegisterErrorConstants.getErrorMsg(errorCode);

        // XML 내용 생성
        Document xmlDoc = makeErrorXML(contentId, errorCode, errorMsg, DateUtil.getToday() + DateUtil.getTime());

        File file = new File(filePath);
        FileOutputStream out = null;

        try {

            if(!file.exists()) { // 로그 파일 없으면 생성

                File dir = new File(ftpRepoPath); // ftp 디렉토리가 없으면 생성
                if(!dir.exists())
                    dir.mkdir();

                file.createNewFile();
            }

            out = new FileOutputStream(file);
            XMLOutputter serializer = new XMLOutputter();
            serializer.output(xmlDoc, out);
            out.flush();
        }
        catch (IOException e) {

            log.error("BatchRegisterError.makeErrorLog 로그 파일 작성 중 예외 발생", e);
            throw e;
        }
        finally {

            if(out != null) {

                try {

                    out.close();
                }
                catch (IOException e) {

                    log.error("BatchRegisterError.makeErrorLog 로그 파일 작성 종료 중 예외 발생", e);
                }
            }
        }
    }

    /**
     * 에러 메시지를 담는 XML을 생성 후 반환
     * @param contentId
     * @param errorCode
     * @param errorMsg
     * @param dateTime
     * @return
     */
    private Document makeErrorXML(String contentId, int errorCode, String errorMsg, String dateTime) {

        Document doc = new Document();

        Element error_log = new Element("error_log"); // root

        Element content_id = new Element("content_id");
        content_id.setAttribute("id", contentId); // set CID

        Element msg = new Element("msg");
        msg.setText(errorMsg);

        Element code = new Element("code");
        code.setText(String.valueOf(errorCode));

        Element time = new Element("time");
        time.setText(DateUtil.getToday() + DateUtil.getTime());

        content_id.addContent(msg);
        content_id.addContent(code);
        content_id.addContent(time);

        error_log.addContent(content_id);

        doc.addContent(error_log);

        return doc;
    }
}


볼드체를 참고하기

java.util.concurrent 패키지
- 일반 자바 Thread 클래스보다 높은 수준의 동시성 프로그래밍을 지원한다...고 함.
- ExecutorService 클래스는 하나 이상의 스레드를 관리하며, 작업(Runnable이나 Callable 인스턴스)이 실행되도록 실행기(ExecutorService 인스턴스)에 넘겨주면 된다.
  그러면 Future 클래스의 인스턴스를 반환되는데, 이 Future클래스는 실행시킨 작업이 반환할, 아직 알 수 없는 값을 참조한다.
 (1) transThread = Executors.newSingleThreadExecutor(); // 실행기 얻기
 (2) transPending = transThread.submit(translateTask); // ExecutorService에 작업(translateTask 쓰레드)를 넘기고 결과를 Future(transPending)로 받음.

외부 스레드에서 Android GUI 스레드의 유저 인터페이스 업데이트 하기
   /**
     * 화면의 텍스트 수정하기(다른 스레드에서 호출됨)
     * @param text
     */
    public void setTranslated(String text) {

        guiSetText(transText, text);
    }

    /**
     * 화면의 텍스트 수정하기(다른 스레드에서 호출됨)
     * @param text
     */
    public void setRetranslated(String text) {

        guiSetText(retransText, text);
    }

   /**
     * GUI 관련한 변경은 모두 GUI스레드에서 이루어져야 한다.<br>
     * 외부 스레드(유저 인터페이스가 아닌)에서 유저 인터페이스 관련 함수를 호출할 수 없음. 외부 스레드에서 GUI스레드에게 유저 인터페이스를 업데이트하라고 요청.
     * @param view
     * @param text
     */
    private void guiSetText(final TextView view, final String text) {

        guiThread.post(new Runnable() {

            @Override
            public void run() {

                view.setText(text);
            }
        });
    }
setTranslated(), setRetranslated() 메소드가 외부 스레드에서 불림 -> guiSetText() 메소드가 실행됨. -> 유저 인터페이스 업데이트

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

[TDD] 안드로이드 TDD 개발하기  (0) 2010.11.15
[Hello,Android] Android <-> WebView 간 호출하기  (1) 2010.08.31
[Hello,World] Sudoku  (0) 2010.08.31
[Hello,Android] Audio, Video  (0) 2010.08.30
[tip] LogCat 문자깨짐  (0) 2010.08.18