====== Compress/Decompress 서비스 ======
===== 개요 =====
**전자정부 프레임워크**에서는 다양한 압축방식을 개발자들에게 편리한 API를 제공하는 Jakarta Commons의 Compress를 오픝소스로 채택하였다.
Jakarta Commons의 Compress에서 지원하는 tar, zip, bzip2, 7z 파일 등을 지원한다.
현재 Commons Compress 1.6 API 에서는
org.apache.commons.compress.archivers
org.apache.commons.compress.archivers.ar
org.apache.commons.compress.archivers.arj
org.apache.commons.compress.archivers.cpio
org.apache.commons.compress.archivers.dump
org.apache.commons.compress.archivers.jar
org.apache.commons.compress.archivers.sevenz
org.apache.commons.compress.archivers.tar
org.apache.commons.compress.archivers.zip
org.apache.commons.compress.changes
org.apache.commons.compress.compressors
org.apache.commons.compress.compressors.bzip2
org.apache.commons.compress.compressors.gzip
org.apache.commons.compress.compressors.lzma
org.apache.commons.compress.compressors.pack200
org.apache.commons.compress.compressors.xz
org.apache.commons.compress.utils
의 Packages를 제공하고 있다.
보다 자세한 사항은 [[http://commons.apache.org/proper/commons-compress/javadocs/api-1.6/index.html|Commons Compress 1.6 API]]를 참고하기 바란다.
===== 설명 =====
**압축**이란 파일에 저장되어 있는 정보를 압축하여 보다 적은 기억 공간에 동일한 정보를 저장하는 기술이다.
일반적으로 정보에 포함되어 있는 중복된 내용을 삭제하거나 보다 적은 길이의 코드를 사용하여 정보를 표현하는 방법을 사용하여 저장에 필요한 공간의 크기를 줄인다.
이런 과정을 압축이라고 하며, 압축된 정보를 사용하기 위해서 다시 원래의 상태로 복원하는 과정을 압축해제라고 한다.
압축 방법에는 손실이 없는 압축 방법과 손실이 있는 압축 방법이 있다.
먼저 프로그램과 데이터 등과 같은 정보는 반드시 손실이 없는 압축 방법을 사용하여야 한다.
손실이 없는 압축 방법이라고 하는 것은 압축된 정보를 다시 복원한 경우에 압축되기 이전의 상태와 동일한 내용과 크기를 가지게 되는 압축 방법을 말한다.
하지만 이미지나 음성 등과 같은 경우에는 손실이 있는 압축 방법을 사용할 수 있다.
이미지나 음성에는 방대한 양의 정보가 존재하고 이들 정보 중에 일부가 사라진다 하더라도 사람이 눈이나 귀로 그 차이를 구별할 수 없기 때문이다.
손실이 있는 압축 방법이라고 하는 것은 압축된 정보를 다시 복원하더라도 압축되기 이전의 상태 혹은 크기와 동일하지 않은 내용을 가질 수 있는 압축 방법을 뜻한다.
간단히 여기서는 자주 사용하는 압축파일의 종류는 아래의 참조 링크를 참고한다.
*[[.:압축파일의 종류:압축파일의 종류]]
===== 사용 예제 =====
다음은 테스트코드 EgovZipTestCase의 testZipArchiveCreation() 메소드로 org.apache.commons.compress.archivers 패키지에 속한
ArchiveInputStream 클래스를 사용하여 compress/decompress로 구성되어 있다.
public final class EgovZipTestCase {
private File dir;
private File resultDir;
private File file1;
private File file2;
/*
* Zip을 사용한 압축(Archive) TEST
* 두개의 파일(test1.xml, test2.xml)을 사용하여 압축하여 bla.zip으로 압축함
*/
public void testZipArchiveCreation() throws Exception {
// Archive
dir = mkdir("dir");
resultDir = mkdir("dir-result");
final File output = new File(dir, "bla.zip");
file1 = getFile("test1.xml");
file2 = getFile("test2.xml");
final OutputStream out = new FileOutputStream(output);
ArchiveOutputStream os = null;
try {
os = new ArchiveStreamFactory().createArchiveOutputStream("zip", out); // 첫번째 파라미터에 "jar", "tar" 등을 사용하여 포맷 설정
os.putArchiveEntry(new ZipArchiveEntry("test1.xml"));
IOUtils.copy(new FileInputStream(file1), os);
os.closeArchiveEntry();
os.putArchiveEntry(new ZipArchiveEntry("test2.xml"));
IOUtils.copy(new FileInputStream(file2), os);
os.closeArchiveEntry();
} finally {
if (os != null) {
os.close();
}
}
out.close();
}
/*
* Zip 파일 압축해제 TEST
* bla.zip 파일을 압축해제 (test1.xml, test2.xml)
*/
public void testZipUnarchive() throws Exception {
List results = new ArrayList();
final File input = new File(dir, "bla.zip");
final InputStream is = new FileInputStream(input);
ArchiveInputStream in = null;
try {
in = new ArchiveStreamFactory().createArchiveInputStream("zip", is); // 첫번째 파라미터에 "jar", "tar" 등을 사용하여 포맷 설정
ZipArchiveEntry entry = null;
while((entry = (ZipArchiveEntry)in.getNextEntry()) != null) {
File outfile = new File(resultDir.getCanonicalPath() + "/" + entry.getName());
outfile.getParentFile().mkdirs();
OutputStream o = new FileOutputStream(outfile);
try {
IOUtils.copy(in, o);
} finally {
o.close();
}
results.add(outfile);
}
} finally {
if (in != null) {
in.close();
}
}
is.close();
assertEquals(results.size(), 2);
File result = results.get(0);
assertEquals(file1.length(), result.length());
result = results.get(1);
assertEquals(file2.length(), result.length());
}
public static File mkdir(String name) throws IOException {
File f = File.createTempFile(name, "");
f.delete();
f.mkdir();
return f;
}
public static File getFile(String path) throws IOException {
URL url = EgovZipTestCase.class.getClassLoader().getResource(path);
if (url == null) {
throw new FileNotFoundException("couldn't find " + path);
}
URI uri = null;
try {
uri = url.toURI();
} catch (java.net.URISyntaxException ex) {
IOException ioe = new IOException();
ioe.initCause(ex);
throw ioe;
}
return new File(uri);
}
}
===== N. 참고자료 =====
[[http://commons.apache.org/compress/index.html|Apache Commons Compress]]
[[http://commons.apache.org/proper/commons-compress/javadocs/api-1.6/index.html|Commons Compress 1.6 API]]