Accessing zips and jars using Java Part 2
This is the second half of a two part series on accessing zip and jar files using Java. In part one, we explained how to get the table of contents of a zip file or a jar file and how to get the manifest of a jar file. In this part, we'll show you how to create, add files to, and extract files from zips and jars.
CreatingCreating a zip file is easy. Only three lines of code are required:
ZipOutputStream zip =
new ZipOutputStream(new FileOutputStream("simple.zip"));
To create a jar file, you use the JarOutputStream and JarEntry classes instead of the ZipOutputStream and ZipEntry classes, like this:
JarOutputStream jar =
new JarOutputStream(new FileOutputStream("simple.jar"));
Notice that in both of the code fragments above we add a stub entry. This is necessary because closing a zip file or a jar file that does not have any entries will throw an exception. Also, note that if the zip file or jar file exists, it will be overwritten.
AddingAdding files to a zip file requires a little more code than getting the table of contents but is not much more difficult. Here is an example program, ZipCreate, that creates a zip file and adds files to it (like the jar tool does when the "c" switch is specified). Both the zip file name and the names of the files to add are read from command-line arguments.
The algorithm for ZipCreate is:
- Create a zip output stream for the specified zip file.
- Allocate a buffer for reading the input files.
- Loop through the command-line arguments, starting at the second one. For each:
- Open the named file.
- Create a zip entry for the file.
- Add the zip entry to the zip.
- Read the file data and write it to the zip output stream. (The data will be compressed automatically using the default compression method.)
- Close the file.
- Close the zip output stream.
To create a jar file and add files to it, you use the algorithm above, but you use the jar classes instead of the zip classes. An example program for doing this, JarCreate, is here.
Note that methods for adding all files that match a given pattern are not provided by the zip and jar classes. You will have to obtain or write your own code for that.
ExtractingExtracting files from a zip file is no more complicated than adding files. You just use different classes. Here is an example program, ZipExtract, that extracts a given file from a given zip file. Both the name of the zip file and the name of the file to extract are read from command-line arguments.
The algorithm for ZipExtract is:
- Get the name of the zip file and the name of the file to extract.
- Open the zip file.
- Get the zip entry that corresponds to the given file.
- If the zip entry is found:
- Get an input stream for the zip entry.
- Create an output stream for the file to extract.
- Allocate a buffer for reading the zip entry data.
- Read the zip entry data and write it to the file output stream. (The zip entry data will be decompressed as it is read.)
- Close the file output stream.
- Close the zip entry input stream. Otherwise, print an error message.
- Close the zip file.
To extract a file from a jar file, you use the algorithm above, but use the jar classes instead of the zip classes. An example program for doing this, JarExtract, is here.
Note that in ZipExract and JarExtract I do not check for path names. In a real program, you would want to do this, so that you could create directories as you extract files.
UpdatingUpdating an existing zip file or jar file gets tricky, because the zip and jar classes do not provide truly random access to zip files and jar files. The ZipFile and JarFile classes have a method for getting a specific entry but not for adding an entry. The ZipInputStream and JarInputStream classes have a method for adding an entry but not for getting a specific entry. So, updating a zip file or a jar file will often require the use of a temporary file.
Here is an example program, JarUpdate, that updates a specific entry in an existing jar file.
The algorithm for JarUpdate is:
- Get the jar name and the file name from the command-line arguments.
- Create file objects for the jar file and a temporary jar file.
- Open the jar file.
- Create the temporary jar file, with no manifest. (The manifest will be copied from the original jar file.)
- Allocate a buffer for reading file data.
- Open the specified file.
- Create an entry in the temporary jar for the specified file.
- Read the file data and write it to the temporary jar.
- Loop through the entries of the original jar file, skipping the entry that was added to the temporary jar. For each entry:
- Get an input stream for the entry.
- Read the entry data and write it to the temporary jar.
- Close the temporary jar file.
- Close the original jar file.
- If the temporary jar file was created without an exception, delete the original jar file and change the name the temporary file to the name of original jar file. Otherwise, delete the temporary jar file.
To update an existing zip file, you would use the algorithm above but would use the zip classes instead of the jar classes. This is left as an exercise for the reader.
Note that in JarUpdate we assume the default compression method for both the original jar file and the temporary jar file. In a real program, you would want to make sure that the same compression method is used for the entries in both jar files.
About the authorThornton Rose is a software developer who lives and works in Atlanta, Georgia. He can be reached via e-mail at email@example.com.