요구사항
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 발생
'Java' 카테고리의 다른 글
Java Poi 엑셀 이미지 삽입하기 (0) | 2025.02.11 |
---|---|
String Constants Pool (0) | 2020.11.15 |
클린 코드 작성 : 더 나은 개발자가 되기 위한 단계 (0) | 2020.11.15 |
Java(JVM) Memory Model(Runtime Data Areas) (0) | 2020.10.21 |
Static 사용을 피해야 하는 이유 (2) | 2020.10.20 |
댓글