public static void unzip ( File zipFile , File destDir ) throws IOException { final ZipFile zip = new ZipFile ( zipFile ) ; try { final Set < File > createdDirs = new HashSet < File > ( ) ; final Enumeration < ? extends ZipEntry > entries = zip . entries ( ) ; FILES_LOOP : while ( entries . hasMoreElements ( ) ) { final ZipEntry zipEntry = entries . nextElement ( ) ; final String name = zipEntry . getName ( ) ; final List < String > tokens = PathTokenizer . getTokens ( name ) ; final Iterator < String > it = tokens . iterator ( ) ; File current = destDir ; while ( it . hasNext ( ) ) { String token = it . next ( ) ; if ( PathTokenizer . isCurrentToken ( token ) || PathTokenizer . isReverseToken ( token ) ) { // invalid file; skip it! continue FILES_LOOP ; } current = new File ( current , token ) ; if ( ( it . hasNext ( ) || zipEntry . isDirectory ( ) ) && createdDirs . add ( current ) ) { current . mkdir ( ) ; } } if ( ! zipEntry . isDirectory ( ) ) { final InputStream is = zip . getInputStream ( zipEntry ) ; try { final FileOutputStream os = new FileOutputStream ( current ) ; try { VFSUtils . copyStream ( is , os ) ; // allow an error on close to terminate the unzip is . close ( ) ; os . close ( ) ; } finally { VFSUtils . safeClose ( os ) ; } } finally { VFSUtils . safeClose ( is ) ; } // exclude jsp files last modified time change. jasper jsp compiler Compiler.java depends on last modified time-stamp to re-compile jsp files if ( ! current . getName ( ) . endsWith ( ".jsp" ) ) current . setLastModified ( zipEntry . getTime ( ) ) ; } } } finally { VFSUtils . safeClose ( zip ) ; } }
Expand a zip file to a destination directory . The directory must exist . If an error occurs the destination directory may contain a partially - extracted archive so cleanup is up to the caller .