diff --git a/src/main/java/cokr/xit/base/file/ZIP.java b/src/main/java/cokr/xit/base/file/ZIP.java new file mode 100644 index 0000000..d820a57 --- /dev/null +++ b/src/main/java/cokr/xit/base/file/ZIP.java @@ -0,0 +1,94 @@ +package cokr.xit.base.file; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.Arrays; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; + +import cokr.xit.foundation.Assert; + +public class ZIP { + public File compress(String zipPath, String... targets) { + return compress(zipPath, Arrays.asList(targets)); + } + + public File compress(String zipPath, List targets) { + try ( + FileOutputStream fout = new FileOutputStream(zipPath); + ZipOutputStream zout = new ZipOutputStream(fout); + ) { + for (String path: targets) + compress(zout, path); + + return new File(zipPath); + } catch(Exception e) { + throw Assert.runtimeException(e); + } + } + + private void compress(ZipOutputStream zout, String path) throws Exception { + File file = new File(path); + try (FileInputStream fis = new FileInputStream(file);) { + zout.putNextEntry(new ZipEntry(file.getName())); + byte[] bytes = new byte[1024]; + int length; + while((length = fis.read(bytes)) >= 0) { + zout.write(bytes, 0, length); + } + } + } + + public void decompress(String zipPath, String destDir) { + try ( + FileInputStream fis = new FileInputStream(zipPath); + ZipInputStream zis = new ZipInputStream(fis); + ) { + decompress(zis, destDir); + } catch (Exception e) { + throw Assert.runtimeException(e); + } + } + + private void decompress(ZipInputStream zis, String destDir) throws Exception { + byte[] buff = new byte[1024]; + File dir = new File(destDir); + + ZipEntry zipEntry = zis.getNextEntry(); + while (zipEntry != null) { + File newFile = newFile(dir, zipEntry); + + if (zipEntry.isDirectory()) { + if (!newFile.isDirectory() && !newFile.mkdirs()) + throw new Exception("Failed to create directory " + newFile); + } else { + File parent = newFile.getParentFile(); + if (!parent.isDirectory() && !parent.mkdirs()) + throw new Exception("Failed to create directory " + parent); + + try ( + FileOutputStream fos = new FileOutputStream(newFile); + ) { + int len; + while ((len = zis.read(buff)) > 0) { + fos.write(buff, 0, len); + } + } + } + zipEntry = zis.getNextEntry(); + } + } + + private File newFile(File destDir, ZipEntry zipEntry) throws Exception { + File destFile = new File(destDir, zipEntry.getName()); + + String destDirPath = destDir.getCanonicalPath(); + if (!destFile.getCanonicalPath().startsWith(destDirPath + File.separator)) + throw new Exception(String.format("%s is outside of the %s", zipEntry.getName(), destDirPath)); + + return destFile; + } +} \ No newline at end of file