Hi folks.
I've recently been working with zip files and saw that commons IO did not
support them.
May I suggest that a ZipUtils class is added to commons IO, perhaps with my
meagre contribution
which has one simple function: expand a zip file from an input stream to a
directory. (and a support
function which could go into IOUtils)
Cheers
Peter Henderson.
/*
* ZipUtils.java
*
* Created on 22-Jul-2008
*/
package org.apache.commons.io;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* Utility classes to simplify working with zip files and streams.
*
* @author peter
*/
public class ZipUtils {
/**
* Copy the contents of a zip stream to a directory.
* Can be used to copy resource streams within the applications jar to
* disk.
* The directory structure in the zip file is maintained.
*
* Example usage
* <pre>
* InputStream is =
this.getClass().getResourceAsStream("/res/test.zip");
* ZipUtils.expandZip(is, new File("/tmp"));
* </pre>
*
*
* @param is input stream reading a zip file
* @param dir the directory to expand the content of the zip into. The
* directory is created if it does not already exist
* @throws java.io.IOException
* if the directory could not be created,
* an entry could not be loaded from the stream,
* an output stream could not be opened,
* an zip entry contents could not be read
*/
public static void expandZip(InputStream is, File dir) throws IOException {
if (!dir.exists()) {
FileUtils.forceMkdir(dir);
}
ZipInputStream zipIS = new ZipInputStream(is);
ZipEntry entry = zipIS.getNextEntry();
while (entry != null) {
//System.out.format("Entry %s\n", entry.getName());
File f = new File(dir, entry.getName());
if (entry.isDirectory()) {
f.mkdir();
} else {
FileOutputStream fileOS = FileUtils.openOutputStream(f);
// @TODO move copy with length funtion in to IOUtils.
copy(zipIS, fileOS, entry.getSize());
fileOS.close();
}
entry = zipIS.getNextEntry();
}
}
//
// TODO add this to IOUtils
//
/**
* The default buffer size to use.
*/
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
/**
* Copy <code>length</code> bytes from an <code>InputStream</code> to an
* <code>OutputStream</code>.
* <p>
* This method buffers the input internally, so there is no need to use a
* <code>BufferedInputStream</code>.
*
* @param input the <code>InputStream</code> to read from
* @param output the <code>OutputStream</code> to write to
* @param length the number of bytes to copy
* @throws NullPointerException if the input or output is null
* @throws IllegalArgumentException if length is negative
* @throws IOException if the input stream does not contain enough data to
* copy or an I/O error occurs
* @since Commons IO 1.4
*/
public static void copy(InputStream input, OutputStream output, long length)
throws IOException {
if (length < 0) {
throw new IllegalArgumentException("Length is less than " +
"zero, cannot copy a negative number of bytes?");
}
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
long written = 0;
while (written != length) {
long outstanding = length - written;
int toRead;
if (outstanding > buffer.length) {
toRead = buffer.length;
} else {
toRead = (int) outstanding;
}
int read = input.read(buffer, 0, toRead);
if (read == -1) {
throw new IOException(
"Input stream does not contain enough data");
}
output.write(buffer, 0, read);
written += read;
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]