Java Zip Folder zip(File rootDir, String zipPath)

Here you can find the source of zip(File rootDir, String zipPath)

Description

zip

License

Open Source License

Declaration

public static void zip(File rootDir, String zipPath) throws IOException 

Method Source Code

//package com.java2s;
/*******************************************************************************
 * Copyright (c) 2000, 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors://from   w  w w.  j a  v  a2 s. c  om
 *     IBM Corporation - initial API and implementation
 *     Nina Rinskaya
 *           Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=172820.
 *******************************************************************************/

import java.io.*;

import java.util.zip.*;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;

public class Main {
    private static int DELETE_MAX_TIME = 0;
    /**
     * Trace deletion operations while running JDT/Core tests.
     */
    public static boolean DELETE_DEBUG = false;
    /**
     * Maximum of time in ms to wait in deletion operation while running JDT/Core tests.
     * Default is 10 seconds. This number cannot exceed 1 minute (ie. 60000).
     * <br>
     * To avoid too many loops while waiting, the ten first ones are done waiting
     * 10ms before repeating, the ten loops after are done waiting 100ms and
     * the other loops are done waiting 1s...
     */
    public static int DELETE_MAX_WAIT = 10000;

    public static void zip(File rootDir, String zipPath) throws IOException {
        ZipOutputStream zip = null;
        try {
            File zipFile = new File(zipPath);
            if (zipFile.exists()) {
                if (!delete(zipFile))
                    throw new IOException("Could not delete " + zipPath);
                // ensure the new zip file has a different timestamp than the previous one
                int timeToWait = 1000; // some platform (like Linux) have a 1s granularity)
                waitAtLeast(timeToWait);
            } else {
                zipFile.getParentFile().mkdirs();
            }
            zip = new ZipOutputStream(new FileOutputStream(zipFile));
            zip(rootDir, zip, rootDir.getPath().length() + 1); // 1 for last slash
        } finally {
            if (zip != null) {
                zip.close();
            }
        }
    }

    private static void zip(File dir, ZipOutputStream zip, int rootPathLength) throws IOException {
        File[] files = dir.listFiles();
        if (files != null) {
            for (int i = 0, length = files.length; i < length; i++) {
                File file = files[i];
                if (file.isFile()) {
                    String path = file.getPath();
                    path = path.substring(rootPathLength);
                    ZipEntry entry = new ZipEntry(path.replace('\\', '/'));
                    zip.putNextEntry(entry);
                    zip.write(org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(file));
                    zip.closeEntry();
                } else {
                    zip(file, zip, rootPathLength);
                }
            }
        }
    }

    /**
     * Delete a file or directory and insure that the file is no longer present
     * on file system. In case of directory, delete all the hierarchy underneath.
     *
     * @param file The file or directory to delete
     * @return true iff the file was really delete, false otherwise
     */
    public static boolean delete(File file) {
        // flush all directory content
        if (file.isDirectory()) {
            flushDirectoryContent(file);
        }
        // remove file
        file.delete();
        if (isFileDeleted(file)) {
            return true;
        }
        return waitUntilFileDeleted(file);
    }

    /**
     * Delete a file or directory and insure that the file is no longer present
     * on file system. In case of directory, delete all the hierarchy underneath.
     *
     * @param resource The resource to delete
     * @return true iff the file was really delete, false otherwise
     */
    public static boolean delete(IResource resource) {
        try {
            resource.delete(true, null);
            if (isResourceDeleted(resource)) {
                return true;
            }
        } catch (CoreException e) {
            //   skip
        }
        return waitUntilResourceDeleted(resource);
    }

    /**
     * Delete a file or directory and insure that the file is no longer present
     * on file system. In case of directory, delete all the hierarchy underneath.
     *
     * @param path The path of the file or directory to delete
     * @return true iff the file was really delete, false otherwise
     */
    public static boolean delete(String path) {
        return delete(new File(path));
    }

    public static void waitAtLeast(int time) {
        long start = System.currentTimeMillis();
        do {
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
            }
        } while ((System.currentTimeMillis() - start) < time);
    }

    /**
     * Flush content of a given directory (leaving it empty),
     * no-op if not a directory.
     */
    public static void flushDirectoryContent(File dir) {
        File[] files = dir.listFiles();
        if (files == null)
            return;
        for (int i = 0, max = files.length; i < max; i++) {
            delete(files[i]);
        }
    }

    /**
     * Returns whether a file is really deleted or not.
     * Does not only rely on {@link File#exists()} method but also
     * look if it's not in its parent children {@link #getParentChildFile(File)}.
     *
     * @param file The file to test if deleted
     * @return true if the file does not exist and was not found in its parent children.
     */
    public static boolean isFileDeleted(File file) {
        return !file.exists() && getParentChildFile(file) == null;
    }

    /**
     * Wait until the file is _really_ deleted on file system.
     *
     * @param file Deleted file
     * @return true if the file was finally deleted, false otherwise
     */
    private static boolean waitUntilFileDeleted(File file) {
        if (DELETE_DEBUG) {
            System.out.println();
            System.out.println("WARNING in test: " + getTestName());
            System.out.println("   - problems occured while deleting " + file);
            printJdtCoreStackTrace(null, 1);
            printFileInfo(file.getParentFile(), 1, -1); // display parent with its children
            System.out.print("   - wait for (" + DELETE_MAX_WAIT + "ms max): ");
        }
        int count = 0;
        int delay = 10; // ms
        int maxRetry = DELETE_MAX_WAIT / delay;
        int time = 0;
        while (count < maxRetry) {
            try {
                count++;
                Thread.sleep(delay);
                time += delay;
                if (time > DELETE_MAX_TIME)
                    DELETE_MAX_TIME = time;
                if (DELETE_DEBUG)
                    System.out.print('.');
                if (file.exists()) {
                    if (file.delete()) {
                        // SUCCESS
                        if (DELETE_DEBUG) {
                            System.out.println();
                            System.out.println("   => file really removed after " + time + "ms (max="
                                    + DELETE_MAX_TIME + "ms)");
                            System.out.println();
                        }
                        return true;
                    }
                }
                if (isFileDeleted(file)) {
                    // SUCCESS
                    if (DELETE_DEBUG) {
                        System.out.println();
                        System.out.println(
                                "   => file disappeared after " + time + "ms (max=" + DELETE_MAX_TIME + "ms)");
                        System.out.println();
                    }
                    return true;
                }
                // Increment waiting delay exponentially
                if (count >= 10 && delay <= 100) {
                    count = 1;
                    delay *= 10;
                    maxRetry = DELETE_MAX_WAIT / delay;
                    if ((DELETE_MAX_WAIT % delay) != 0) {
                        maxRetry++;
                    }
                }
            } catch (InterruptedException ie) {
                break; // end loop
            }
        }
        if (!DELETE_DEBUG) {
            System.out.println();
            System.out.println("WARNING in test: " + getTestName());
            System.out.println("   - problems occured while deleting " + file);
            printJdtCoreStackTrace(null, 1);
            printFileInfo(file.getParentFile(), 1, -1); // display parent with its children
        }
        System.out.println();
        System.out.println("   !!! ERROR: " + file + " was never deleted even after having waited "
                + DELETE_MAX_TIME + "ms!!!");
        System.out.println();
        return false;
    }

    /**
     * Returns whether a resource is really deleted or not.
     * Does not only rely on {@link IResource#isAccessible()} method but also
     * look if it's not in its parent children {@link #getParentChildResource(IResource)}.
     *
     * @param resource The resource to test if deleted
     * @return true if the resource is not accessible and was not found in its parent children.
     */
    public static boolean isResourceDeleted(IResource resource) {
        return !resource.isAccessible() && getParentChildResource(resource) == null;
    }

    /**
     * Wait until a resource is _really_ deleted on file system.
     *
     * @param resource Deleted resource
     * @return true if the file was finally deleted, false otherwise
     */
    public static boolean waitUntilResourceDeleted(IResource resource) {
        IPath location = resource.getLocation();
        if (location == null) {
            System.out.println();
            System.out.println("   !!! ERROR: " + resource + " getLocation() returned null!!!");
            System.out.println();
            return false;
        }
        File file = location.toFile();
        if (DELETE_DEBUG) {
            System.out.println();
            System.out.println("WARNING in test: " + getTestName());
            System.out.println("   - problems occured while deleting resource " + resource);
            printJdtCoreStackTrace(null, 1);
            printFileInfo(file.getParentFile(), 1, -1); // display parent with its children
            System.out.print("   - wait for (" + DELETE_MAX_WAIT + "ms max): ");
        }
        int count = 0;
        int delay = 10; // ms
        int maxRetry = DELETE_MAX_WAIT / delay;
        int time = 0;
        while (count < maxRetry) {
            try {
                count++;
                Thread.sleep(delay);
                time += delay;
                if (time > DELETE_MAX_TIME)
                    DELETE_MAX_TIME = time;
                if (DELETE_DEBUG)
                    System.out.print('.');
                if (resource.isAccessible()) {
                    try {
                        resource.delete(true, null);
                        if (isResourceDeleted(resource) && isFileDeleted(file)) {
                            // SUCCESS
                            if (DELETE_DEBUG) {
                                System.out.println();
                                System.out.println("   => resource really removed after " + time + "ms (max="
                                        + DELETE_MAX_TIME + "ms)");
                                System.out.println();
                            }
                            return true;
                        }
                    } catch (CoreException e) {
                        //   skip
                    }
                }
                if (isResourceDeleted(resource) && isFileDeleted(file)) {
                    // SUCCESS
                    if (DELETE_DEBUG) {
                        System.out.println();
                        System.out.println(
                                "   => resource disappeared after " + time + "ms (max=" + DELETE_MAX_TIME + "ms)");
                        System.out.println();
                    }
                    return true;
                }
                // Increment waiting delay exponentially
                if (count >= 10 && delay <= 100) {
                    count = 1;
                    delay *= 10;
                    maxRetry = DELETE_MAX_WAIT / delay;
                    if ((DELETE_MAX_WAIT % delay) != 0) {
                        maxRetry++;
                    }
                }
            } catch (InterruptedException ie) {
                break; // end loop
            }
        }
        if (!DELETE_DEBUG) {
            System.out.println();
            System.out.println("WARNING in test: " + getTestName());
            System.out.println("   - problems occured while deleting resource " + resource);
            printJdtCoreStackTrace(null, 1);
            printFileInfo(file.getParentFile(), 1, -1); // display parent with its children
        }
        System.out.println();
        System.out.println("   !!! ERROR: " + resource + " was never deleted even after having waited "
                + DELETE_MAX_TIME + "ms!!!");
        System.out.println();
        return false;
    }

    /**
     * Returns the parent's child file matching the given file or null if not found.
     *
     * @param file The searched file in parent
     * @return The parent's child matching the given file or null if not found.
     */
    private static File getParentChildFile(File file) {
        File parent = file.getParentFile();
        if (parent == null || !parent.exists())
            return null;
        File[] files = parent.listFiles();
        int length = files == null ? 0 : files.length;
        if (length > 0) {
            for (int i = 0; i < length; i++) {
                if (files[i] == file) {
                    return files[i];
                } else if (files[i].equals(file)) {
                    return files[i];
                } else if (files[i].getPath().equals(file.getPath())) {
                    return files[i];
                }
            }
        }
        return null;
    }

    /**
     * Returns the test name from stack elements info.
     *
     * @return The name of the test currently running
     */
    private static String getTestName() {
        StackTraceElement[] elements = new Exception().getStackTrace();
        int idx = 0, length = elements.length;
        while (idx < length && !elements[idx++].getClassName().startsWith("org.eclipse.jdt")) {
            // loop until JDT/Core class appears in the stack
        }
        if (idx < length) {
            StackTraceElement testElement = null;
            while (idx < length && elements[idx].getClassName().startsWith("org.eclipse.jdt")) {
                testElement = elements[idx++];
            }
            if (testElement != null) {
                return testElement.getClassName() + " - " + testElement.getMethodName();
            }
        }
        return "?";
    }

    /**
     * Print stack trace with only JDT/Core elements.
     *
     * @param exception Exception of the stack trace. May be null, then a fake exception is used.
     * @param indent Number of tab to display before the stack elements to display.
     */
    private static void printJdtCoreStackTrace(Exception exception, int indent) {
        String tab = "";
        for (int i = 0; i < indent; i++)
            tab += "\t";
        StackTraceElement[] elements = (exception == null ? new Exception() : exception).getStackTrace();
        int idx = 0, length = elements.length;
        while (idx < length && !elements[idx++].getClassName().startsWith("org.eclipse.jdt")) {
            // loop until JDT/Core class appears in the stack
        }
        if (idx < length) {
            System.out.print(tab + "- stack trace");
            if (exception == null)
                System.out.println(":");
            else
                System.out.println(" for exception " + exception + ":");
            while (idx < length && elements[idx].getClassName().startsWith("org.eclipse.jdt")) {
                StackTraceElement testElement = elements[idx++];
                System.out.println(tab + "   -> " + testElement);
            }
        } else {
            exception.printStackTrace(System.out);
        }
    }

    /**
     * Print given file information with specified indentation.
     * These information are:<ul>
     *    <li>read {@link File#canRead()}</li>
     *    <li>write {@link File#canWrite()}</li>
     *    <li>exists {@link File#exists()}</li>
     *    <li>is file {@link File#isFile()}</li>
     *    <li>is directory {@link File#isDirectory()}</li>
     *    <li>is hidden {@link File#isHidden()}</li>
     * </ul>
     * May recurse several level in parents hierarchy.
     * May also display children, but then will not recusre in parent
     * hierarchy to avoid infinite loop...
     *
     * @param file The file to display information
     * @param indent Number of tab to print before the information
     * @param recurse Display also information on <code>recurse</code>th parents in hierarchy.
     *    If negative then display children information instead.
     */
    private static void printFileInfo(File file, int indent, int recurse) {
        String tab = "";
        for (int i = 0; i < indent; i++)
            tab += "\t";
        System.out.print(tab + "- " + file.getName() + " file info: ");
        String sep = "";
        if (file.canRead()) {
            System.out.print("read");
            sep = ", ";
        }
        if (file.canWrite()) {
            System.out.print(sep + "write");
            sep = ", ";
        }
        if (file.exists()) {
            System.out.print(sep + "exist");
            sep = ", ";
        }
        if (file.isDirectory()) {
            System.out.print(sep + "dir");
            sep = ", ";
        }
        if (file.isFile()) {
            System.out.print(sep + "file");
            sep = ", ";
        }
        if (file.isHidden()) {
            System.out.print(sep + "hidden");
            sep = ", ";
        }
        System.out.println();
        File[] files = file.listFiles();
        int length = files == null ? 0 : files.length;
        if (length > 0) {
            boolean children = recurse < 0;
            System.out.print(tab + "   + children: ");
            if (children)
                System.out.println();
            for (int i = 0; i < length; i++) {
                if (children) { // display children
                    printFileInfo(files[i], indent + 2, -1);
                } else {
                    if (i > 0)
                        System.out.print(", ");
                    System.out.print(files[i].getName());
                    if (files[i].isDirectory())
                        System.out.print("[dir]");
                    else if (files[i].isFile())
                        System.out.print("[file]");
                    else
                        System.out.print("[?]");
                }
            }
            if (!children)
                System.out.println();
        }
        if (recurse > 0) {
            File parent = file.getParentFile();
            if (parent != null)
                printFileInfo(parent, indent + 1, recurse - 1);
        }
    }

    /**
     * Returns parent's child resource matching the given resource or null if not found.
     *
     * @param resource The searched file in parent
     * @return The parent's child matching the given file or null if not found.
     */
    private static IResource getParentChildResource(IResource resource) {
        IContainer parent = resource.getParent();
        if (parent == null || !parent.exists())
            return null;
        try {
            IResource[] members = parent.members();
            int length = members == null ? 0 : members.length;
            if (length > 0) {
                for (int i = 0; i < length; i++) {
                    if (members[i] == resource) {
                        return members[i];
                    } else if (members[i].equals(resource)) {
                        return members[i];
                    } else if (members[i].getFullPath().equals(resource.getFullPath())) {
                        return members[i];
                    }
                }
            }
        } catch (CoreException ce) {
            // skip
        }
        return null;
    }
}

Related

  1. doZip(Properties properties, String name, File f)
  2. doZip(String baseDir, String fileName)
  3. doZip(String filename, String zipFileName)
  4. doZip(String inFilePath, String outFilePath)
  5. doZipFile(ZipOutputStream zipOut, File file, String dirPath)
  6. zip(File rootDir, String zipPath)
  7. zipDir(File dir, String classPackage, String zipFile)
  8. zipDir(File dir, String relativePath, ZipOutputStream zos)
  9. zipDir(File dir, String relativePath, ZipOutputStream zos, boolean start)