/** This file demonstrates reading the contents of a zip file. It contains a full implementation of a zip file decompressor in a few lines of code. */ /** Unzip the specified file to the specified target directory. args: [filename, targetDir, verbose] filename: a string filename or java.io.File object indicating the file to be unzipped targetDir: a string filename or java.io.File object indicating the target directory to unzip to. verbose: a boolean flag. If this is true, the filenames and sizes will be printed. */ unzipFile[filename, targetDir=".", verbose=false] := { zip = newJava["java.util.zip.ZipFile", filename] for zipEntry = zip.entries[] { // Print size and filename if requested if verbose println[zipEntry.getCompressedSize[] + "\t" + zipEntry.getSize[] + "\t" + zipEntry.getName[]] // Make a File object relevant to the path in the zip file. file = newJava["java.io.File", [targetDir, zipEntry.getName[]]] if zipEntry.isDirectory[] file.mkdirs[] // Create even empty directories else { // This is probably an ordinary file parent = file.getParentFile[] if parent != undef parent.mkdirs[] // Create all parent directories // Open an InputStream from the zip entry and copy it to a file copyStream[zip.getInputStream[zipEntry], newJava["java.io.BufferedOutputStream", [newJava["java.io.FileOutputStream", [file]], 32768]]] } } zip.close[] } /** Return an enumeration of the file (and directory) entries in a zipfile. It returns an enumerating expression of java.util.zip.ZipEntry objects. You can enumerate over this with a "for" loop. */ zipFileEntries[filename] := { zip = newJava["java.util.zip.ZipFile", filename] return zip.entries[] } /** Returns the contents of a subfile in a zip file as a single big string. This converts bytes into characters using the specific encoding. args: [zipFileName, subFile, encoding="UTF-8"] zipFileName: a string filename or java.io.File object indicating the file to be unzipped subFile: a string filename indicating the subfile in the zip file to be extracted. This must be an exact match. encoding: a string which represents the encoding that is assumed to be the encoding of the results. Default is "UTF-8" returns: a string containing the file with the specified encoding applied, or undef if the file cannot be opened. */ zipFileRead[zipFileName, subFile, encoding="UTF-8"] := { istream = zipFileInputStream[zipFileName, subFile] if istream != undef return read[istream, encoding] else return undef } /** Returns the contents of a subfile in a zip file as a series of lines. This converts bytes into characters using the specific encoding. args: [zipFileName, subFile, encoding="UTF-8"] zipFileName: a string filename or java.io.File object indicating the file to be unzipped subFile: a string filename indicating the subfile in the zip file to be extracted. This must be an exact match. encoding: a string which represents the encoding that is assumed to be the encoding of the file. Default is "UTF-8" returns: an enumerating expression of the lines within the file, with the file with the specified encoding applied, or undef if the file cannot be opened. */ zipFileLines[zipFileName, subFile, encoding="UTF-8"] := { istream = zipFileInputStream[zipFileName, subFile] if istream != undef return lines[istream, encoding] else return undef } /** Returns the contents of a file as an InputStream. You don't usually want to use this but rather use the zipFileRead or zipFileLines functions because this doesn't handle Unicode directly. You want to use this if you use the copyStream[inputStream, outputStream] function to write to an external java.io.OutputStream. args: [zipFileName, subFile] zipFileName: a string filename or java.io.File object indicating the file to be unzipped subFile: a string filename indicating the subfile in the zip file to be extracted. This must be an exact match. returns: java.io.InputStream object that will return its contents. */ zipFileInputStream[zipFileName, subFile] := { zip = newJava["java.util.zip.ZipFile", zipFileName] for entry = zip.entries[] if ! entry.isDirectory[] and entry.getName[] == subFile return zip.getInputStream[entry] return undef } // Sample usage (note that a jar file is a zip file.) //unzipFile["../jar/frink.jar", "out", true]