[jboss-svn-commits] JBoss Common SVN: r3323 - jzipfile/trunk/src/main/java/org/jboss/jzipfile.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Jul 2 15:23:05 EDT 2009


Author: david.lloyd at jboss.com
Date: 2009-07-02 15:23:05 -0400 (Thu, 02 Jul 2009)
New Revision: 3323

Modified:
   jzipfile/trunk/src/main/java/org/jboss/jzipfile/Zip.java
Log:
Cache a set of already-created directories so as to avoid hitting the FS every time

Modified: jzipfile/trunk/src/main/java/org/jboss/jzipfile/Zip.java
===================================================================
--- jzipfile/trunk/src/main/java/org/jboss/jzipfile/Zip.java	2009-07-01 12:37:01 UTC (rev 3322)
+++ jzipfile/trunk/src/main/java/org/jboss/jzipfile/Zip.java	2009-07-02 19:23:05 UTC (rev 3323)
@@ -33,6 +33,10 @@
 import java.util.zip.InflaterInputStream;
 import java.util.zip.Inflater;
 import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.Collections;
+import java.util.Set;
+import java.util.HashSet;
 import static java.lang.Math.min;
 import static java.lang.Math.max;
 
@@ -292,16 +296,26 @@
         }
         final byte[] buf = new byte[65536];
         final ZipCatalog catalog = readCatalog(zipFile);
+        final Set<String> createdPaths = new HashSet<String>(256);
         for (ZipEntry zipEntry : catalog.allEntries()) {
             final String name = zipEntry.getName();
             final ZipEntryType entryType = zipEntry.getEntryType();
             if (entryType == ZipEntryType.DIRECTORY) {
-                new File(destDir, name).mkdirs();
+                for (String path : parentPaths(name)) {
+                    if (createdPaths.add(path)) {
+                        new File(destDir, path).mkdir();
+                    }
+                }
             } else if (entryType == ZipEntryType.FILE) {
                 final File file = new File(destDir, name).getCanonicalFile();
-                final File parentFile = file.getParentFile();
-                if (parentFile != null) {
-                    parentFile.mkdirs();
+                final Iterator<String> it = parentPaths(name).iterator();
+                while (it.hasNext()) {
+                    String path = it.next();
+                    if (it.hasNext()) {
+                        if (createdPaths.add(path)) {
+                            new File(destDir, path).mkdir();
+                        }
+                    }
                 }
                 file.delete();
                 final FileOutputStream fos = new FileOutputStream(file);
@@ -329,6 +343,44 @@
         }
     }
 
+    private static Iterable<String> parentPaths(final String wholePath) {
+        final int len = wholePath.length();
+        int n = 0;
+        while (n < len && wholePath.charAt(n) == '/') {
+            n ++;
+        }
+        if (n == len) {
+            return Collections.emptySet();
+        }
+        final int start = n;
+        return new Iterable<String>() {
+            public Iterator<String> iterator() {
+                return new Iterator<String>() {
+                    private int i = start;
+
+                    public boolean hasNext() {
+                        return i < len;
+                    }
+
+                    public String next() {
+                        final int next = wholePath.indexOf('/', i);
+                        if (next == -1) {
+                            i = len;
+                            return wholePath.substring(start);
+                        } else {
+                            i = next + 1;
+                            return wholePath.substring(start, next);
+                        }
+                    }
+
+                    public void remove() {
+                        throw new UnsupportedOperationException();
+                    }
+                };
+            }
+        };
+    }
+
     static void safeClose(final Closeable closeable) {
         try {
             if (closeable != null) closeable.close();




More information about the jboss-svn-commits mailing list