본문 바로가기
Java

Java 디렉토리 전체 압축하기 (+ text 파일로 특정 파일/폴더 만 선택하여 압축하기 )

by kellis 2025. 2. 11.

 

요구사항 

 

1. 아래와 같은 형태의 text 파일을 읽어 특정 폴더 아래의 원하는 항목들만 선택 압축한다. 

Folder          /sample
Folder          /test
File              .png
File              .pdf
File              .results.xlsx
File              .results.unfiltered.tsv.gz

 

2. Folder 는 Nested 하게 중첩된 Folder 전체를 포함한다. 

ex) /sample/first/second/third/forth/fifth/testfile.txt 

 

 

소스코드 

1. 파일리딩 

//압축 원하는 파일을 선택하기 위한 스크립트 텍스트 파일
String filename = "C:/download/script/reading.txt"; 

try {
    //file 입력 스트림을 생성
    FileReader aReader = new FileReader(filename);
    //스트림으로 입력 버퍼를 생성
    BufferedReader aBufReader = new BufferedReader(aReader);

    String aLine = "";
    //텍스트 내용을 한 줄씩 읽어와 aLine에 담고, 이를 aLines에 add 함.
    while ((aLine = aBufReader.readLine()) != null) {
        aLines.add(aLine);
    }

    //버퍼를 닫아줌 ( 파일을 닫아줌 )
    aBufReader.close();
}catch (Exception e){
    e.printStackTrace();
}

 

2. 읽어들인 스크립트 데이터를 기반으로 파일 Zipping 

File zipFile = new File(outputPath, outputName+".results.zip");
byte[] buf = new byte[4096];

try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile))) {
    for (int i = 0; i < aLines.size(); i++) {
        String[] words = aLines.get(i).split("\t");
        //Folder, File check
        String type = words[0];
        //containing string
        String exe = words[1];
        
        //최초 첫라인은 여기서 실행
        switch(type){
            case "Folder":
                String newPath = sourcePath+"/"+exe;
                File dir = new File(newPath);

                //재귀호출을 위한 메소드
                searchDirectory(dir, sourcePath, out);
                
                break;
            case "File":
                File file = new File(sourcePath, sourcePapth+exe);
                
                try (FileInputStream in = new FileInputStream(file)) {
                    ZipEntry ze = new ZipEntry(file.getName());
                    out.putNextEntry(ze);

                    int len;
                    while ((len = in.read(buf)) > 0) {
                        out.write(buf, 0, len);
                    }

                    out.closeEntry();
                }
                break;
        }
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

 

3. 재귀호출을 위한 메소드

private void searchDirectory(File file, String root, ZipOutputStream zos) {
        // 지정된 파일이 디렉토리인지 파일인지 검색
        if (file.isDirectory()) {
            // 디렉토리일 경우 재탐색(재귀)
            File[] files = file.listFiles();
            for (File f : files) {
                log.info("file = > " + f);
                searchDirectory(f, root, zos);
            }
        } else {
            // 파일일 경우 압축을 한다.
            try {
                compressZip(file, root, zos);
            } catch (Throwable e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    private void compressZip(File file, String root, ZipOutputStream zos){
        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) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 

* 재귀호출시 유의해야할 것은 ZipEntry가 쓰인 후에는 반드시 닫혀야 한다는 것! 

* 닫히지 않고 재귀호출이 이루어질 경우 duplicate entry exception 발생 

댓글