Java tutorial
/* * Copyright [2011] [C.H Li http://code.google.com/p/idocbox-common/] * Licensed to the Chunhui Li(C.H Li) under one or more contributor license agreements. * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. * * C.H Li licenses this file to You 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.idocbox.common.file; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; /** * This class used to extract entries in zip file. * @author Chunhui Li email:wiseneuron@gmail.com * @since 0.0.1.1 */ public class ZipExtracter { /** * extract given entry in zip file to destination directory. * if given entry is a directory, extract all folder and files under it to * destination directory. * @param zipFileName name of zip file. * @param entry it can be a directory or a file.(if it is end with "/",it * will be treated as a directory.) . For example, * conf/ represents subdirectory in zip file. * Use "/" to represent root of zip file. * * @param desDir destination directory. * @param startDirLevel the level to start create directory. * Its value is 1,2,... * @throws IOException * @throws ZipException */ public static void extract(final String zipFileName, final String entry, final String desDir, final int... startDirLevel) throws ZipException, IOException { File f = new File(zipFileName); if (f.exists()) { //check destination directory. File desf = new File(desDir); if (!desf.exists()) { desf.mkdirs(); } boolean toExtractDir = false; if (entry.endsWith("/")) { toExtractDir = true; } //create zip file object. ZipFile zf = new ZipFile(f); if (toExtractDir) { Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zf.entries(); ZipEntry ent = null; while (entries.hasMoreElements()) { ent = entries.nextElement(); if (isUnderDir(ent, entry)) { //the entry is under directory //which should to be extracted. //extract the entry. extract(zf, ent, desDir, startDirLevel); } else { //nothing to do. } } } else {//extract given zip entry file to destination directory. ZipEntry zipEntry = zf.getEntry(entry); if (null != zipEntry) { extract(zf, zipEntry, desDir, startDirLevel); } } if (null != zf) { //close zip file. zf.close(); } } } /** * extract given zip entry file from zip file * to given destrination directory. * @param zf ZipFile object. * @param zipEntry zip entry to extract. * @param desDir destrination directory. * @param startDirLevel the level to start create directory. * Its value is 1,2,... * @throws IOException throw the exception whil desDir is no directory. */ private static void extract(final ZipFile zf, final ZipEntry zipEntry, final String desDir, final int... startDirLevel) throws IOException { //check destination directory. File desf = new File(desDir); if (!desf.exists()) { desf.mkdirs(); } int start = 1; if (null != startDirLevel && startDirLevel.length > 0) { start = startDirLevel[0]; if (start < 1) { start = 1; } } String startDir = ""; String zeName = zipEntry.getName(); String folder = zeName; boolean isDir = zipEntry.isDirectory(); if (null != folder) { String[] folders = folder.split("\\/"); if (null != folders && folders.length > 0) { int len = folders.length; if (start == 1) { startDir = zeName; } else { if (start > len) { //nothing to extract. } else { for (int i = start - 1; i < len; i++) { startDir += "/" + folders[i]; } if (null != startDir) { startDir = startDir.substring(1); } } } } } startDir = StringUtils.trim(startDir); if (StringUtils.isNotEmpty(startDir)) { StringBuilder desFileName = new StringBuilder(desDir); if (!desDir.endsWith("/") && !startDir.startsWith("/")) { desFileName.append("/"); } desFileName.append(startDir); File destFile = new File(desFileName.toString()); if (isDir) {//the entry is a dir. if (!destFile.exists()) { destFile.mkdirs(); } } else {//the entry is a file. File parentDir = new File(destFile.getParentFile().getPath()); if (!parentDir.exists()) { parentDir.mkdirs(); } //get entry input stream. InputStream is = zf.getInputStream(zipEntry); OutputStream os = new FileOutputStream(destFile); IOUtils.copy(is, os); if (null != is) { is.close(); } if (null != os) { os.close(); } } } } /** * Is given zip entry under given directory? * @param zipEntry zip entry * @param dir directory in zip file, it is end with "/". * use "/" to represent root of zip file. * For example, conf/ represents subdirectory in zip file. * @return true: the entry is under the directory. * false:the entry is not under the directory. */ private static boolean isUnderDir(final ZipEntry zipEntry, final String dir) { boolean isunder = false; if ("/".equals(dir)) {//dir is root of zip file. return true; } if (null != zipEntry) { String name = zipEntry.getName(); int idx = name.lastIndexOf('/'); if (idx > 0) {//the entry is under sub directory of zip file. String subDir = name.substring(0, idx + 1); if (subDir.startsWith(dir)) { isunder = true; } else { isunder = false; } } else {//the entry is under root directory, but dir is not root. isunder = false; } } return isunder; } }