/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package util.support; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import org.apache.commons.io.DirectoryWalker; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; /** A selection of Zip File based utilities */ public class ZipUtils { public static void zipDirectoryToFile(File directory, final File targetFile) throws IOException { zipDirectoryToFile(directory, targetFile, null); } public static void zipDirectoryToFile(File directory, final File targetFile, String zipPrefix) throws IOException { zipDirectoryToFile(directory, targetFile, new FileFilter() { @Override public boolean accept(File file) { return !file.equals(targetFile); } }, zipPrefix); } private static void zipDirectoryToFile(File directory, final File targetFile, FileFilter filter, String zipPrefix) throws IOException { OutputStream out = new BufferedOutputStream(new FileOutputStream(targetFile)); ZipStreamCreator zipCreator = new ZipStreamCreator(filter, zipPrefix); zipCreator.traverseDirectory(directory, out); } /** @return The contents of the directory Zipped up and converted into an input stream */ public static InputStream directoryToZipInputStream(File directory) throws IOException { return new ByteArrayInputStream(directoryToZipByteArray(directory)); } public static byte[] directoryToZipByteArray(File directory) throws IOException { ZipStreamCreator zipCreator = new ZipStreamCreator(); ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); zipCreator.traverseDirectory(directory, bytesOut); return bytesOut.toByteArray(); } /** Unpacks a Zip into the given directory */ public static void zipInputStreamToDirectory(InputStream zipInputStream, File directory) throws IOException { ZipInputStream zipStream = new ZipInputStream(zipInputStream); try { ZipEntry entry = null; while ((entry = zipStream.getNextEntry()) != null) { File newFile = new File(FilenameUtils.concat(directory.getAbsolutePath(), entry.getName())); if (entry.isDirectory()) { newFile.mkdirs(); } else { newFile.createNewFile(); IOUtils.copy(zipStream, new FileOutputStream(newFile)); } newFile.setLastModified(entry.getTime()); } } finally { IOUtils.closeQuietly(zipStream); } } /** Class used to walk the directory structure and build up the Zip File */ private static class ZipStreamCreator extends DirectoryWalker { private ZipOutputStream outStream; private String startPath; final private String zipPrefix; public ZipStreamCreator() { super(); this.zipPrefix = ""; } public ZipStreamCreator(FileFilter filter, String zipPrefix) { super(filter, -1); if (zipPrefix == null || zipPrefix.equals("")) { this.zipPrefix = ""; } else if (zipPrefix.endsWith("/")) { this.zipPrefix = zipPrefix; } else { this.zipPrefix = zipPrefix + "/"; } } /** * Traverses the directory creating the output zip. The stream is closed * after the zip is created. * * @param startDirectory Starting directory to walk * @param out Output stream.. * @throws java.io.IOException */ public void traverseDirectory(File startDirectory, OutputStream out) throws IOException { startPath = startDirectory.getAbsolutePath(); outStream = new ZipOutputStream(out); try { walk(startDirectory, new ArrayList()); } finally { outStream.flush(); outStream.close(); } } @Override public boolean handleDirectory(File directory, int depth, Collection results) { if (directory.getAbsolutePath().equals(startPath)) { return true; } ZipEntry entry = new ZipEntry(createEntryName(directory) + "/"); try { entry.setTime(directory.lastModified()); outStream.putNextEntry(entry); outStream.closeEntry(); } catch (IOException e) { throw new RuntimeException(e); } return true; } @Override public void handleFile(File file, int depth, Collection results) { // Ignore the target file ZipEntry entry = new ZipEntry(createEntryName(file)); try { entry.setTime(file.lastModified()); outStream.putNextEntry(entry); FileInputStream in = new FileInputStream(file); IOUtils.copy(in, outStream); in.close(); outStream.closeEntry(); } catch (IOException e) { throw new RuntimeException(e); } } private String createEntryName(File file) { return zipPrefix + file.getAbsolutePath().substring(startPath.length() + 1).replace('\\', '/'); } } }