/* * Copyright (c) 2013-2017 Cinchapi Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.cinchapi.concourse.util; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipInputStream; import com.google.common.base.Preconditions; import com.google.common.base.Throwables; import com.google.common.io.CharStreams; /** * A utility class for handling zip files * * @author Jeff Nelson */ public final class ZipFiles { /** * Get the content for the entry at {@code relativeEntryPath} from within * the zip file. * * @param zipPath the path to the zip file * @param relativeEntryPath the path of the entry to extract * @return the content of the entry */ public static String getEntryContent(String zipPath, String relativeEntryPath) { ZipInputStream in = null; try { in = new ZipInputStream(new FileInputStream(zipPath)); ZipEntry entry = in.getNextEntry(); while (entry != null) { if(entry.getName().equals(relativeEntryPath)) { return extract(in); } entry = in.getNextEntry(); } throw new ZipException("Cannot find "+relativeEntryPath); } catch (IOException e) { throw Throwables.propagate(e); } finally { if(in != null) { try { in.closeEntry(); in.close(); } catch (IOException e) { throw Throwables.propagate(e); } } } } /** * Unzip the contents of the file at {@code zipPath} to the * {@code destination} directory. * * @param zipPath the absolute path to the zip file * @param destination the absolute path to the destination */ public static void unzip(String zipPath, String destination) { File dest = new File(destination); if(!dest.exists()) { dest.mkdirs(); } else { Preconditions.checkArgument(dest.isDirectory(), "Unzip destination must be a directory"); } try { ZipInputStream in = new ZipInputStream(new FileInputStream(zipPath)); ZipEntry entry = in.getNextEntry(); while (entry != null) { String target = destination + File.separator + entry.getName(); if(entry.isDirectory()) { new File(target).mkdirs(); } else { extract(in, target); } in.closeEntry(); entry = in.getNextEntry(); } in.close(); } catch (IOException e) { throw Throwables.propagate(e); } } /** * Extract the {@link ZipInputStream#getNextEntry() current entry} from the * {@code in}put stream and place it in the {@code target} path. * * @param in the {@link ZipInputStream} that is correctly positioned at the * desired entry * @param target the target path for the extracted file */ private static void extract(ZipInputStream in, String target) { try { BufferedOutputStream baos = new BufferedOutputStream( new FileOutputStream(target)); byte[] bytesIn = new byte[4096]; int read = 0; while ((read = in.read(bytesIn)) != -1) { baos.write(bytesIn, 0, read); } baos.close(); } catch (IOException e) { throw Throwables.propagate(e); } } /** * Extract and return the content of the * {@link ZipInputStream#getNextEntry() current entry} from the {@code in} * put stream. * * @param in the {@link ZipInputStream} that is correctly positioned at the * desired entry * @return content of the current entry */ private static String extract(ZipInputStream in) { try { return CharStreams.toString(new InputStreamReader(in, StandardCharsets.UTF_8)); } catch (IOException e) { throw Throwables.propagate(e); } } }