diff options
Diffstat (limited to 'src/java/org/apache/poi/util/IOUtils.java')
-rw-r--r-- | src/java/org/apache/poi/util/IOUtils.java | 253 |
1 files changed, 139 insertions, 114 deletions
diff --git a/src/java/org/apache/poi/util/IOUtils.java b/src/java/org/apache/poi/util/IOUtils.java index 4f18214c46..f1d5a2378d 100644 --- a/src/java/org/apache/poi/util/IOUtils.java +++ b/src/java/org/apache/poi/util/IOUtils.java @@ -22,120 +22,149 @@ import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.PushbackInputStream; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; import java.util.zip.CRC32; import java.util.zip.Checksum; +import org.apache.poi.EmptyFileException; + public final class IOUtils { + private static final POILogger logger = POILogFactory.getLogger( IOUtils.class ); + + private IOUtils() { + // no instances of this class + } + + /** + * Peeks at the first 8 bytes of the stream. Returns those bytes, but + * with the stream unaffected. Requires a stream that supports mark/reset, + * or a PushbackInputStream. If the stream has >0 but <8 bytes, + * remaining bytes will be zero. + * @throws EmptyFileException if the stream is empty + */ + public static byte[] peekFirst8Bytes(InputStream stream) throws IOException, EmptyFileException { + // We want to peek at the first 8 bytes + stream.mark(8); + + byte[] header = new byte[8]; + int read = IOUtils.readFully(stream, header); + + if (read < 1) + throw new EmptyFileException(); + + // Wind back those 8 bytes + if(stream instanceof PushbackInputStream) { + PushbackInputStream pin = (PushbackInputStream)stream; + pin.unread(header); + } else { + stream.reset(); + } + + return header; + } + + /** + * Reads all the data from the input stream, and returns the bytes read. + */ + public static byte[] toByteArray(InputStream stream) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + byte[] buffer = new byte[4096]; + int read = 0; + while (read != -1) { + read = stream.read(buffer); + if (read > 0) { + baos.write(buffer, 0, read); + } + } + + return baos.toByteArray(); + } + + /** + * Returns an array (that shouldn't be written to!) of the + * ByteBuffer. Will be of the requested length, or possibly + * longer if that's easier. + */ + public static byte[] toByteArray(ByteBuffer buffer, int length) { + if(buffer.hasArray() && buffer.arrayOffset() == 0) { + // The backing array should work out fine for us + return buffer.array(); + } + + byte[] data = new byte[length]; + buffer.get(data); + return data; + } + + /** + * Helper method, just calls <tt>readFully(in, b, 0, b.length)</tt> + */ + public static int readFully(InputStream in, byte[] b) throws IOException { + return readFully(in, b, 0, b.length); + } + + /** + * Same as the normal <tt>in.read(b, off, len)</tt>, but tries to ensure + * that the entire len number of bytes is read. + * <p> + * If the end of file is reached before any bytes are read, returns -1. If + * the end of the file is reached after some bytes are read, returns the + * number of bytes read. If the end of the file isn't reached before len + * bytes have been read, will return len bytes. + */ + public static int readFully(InputStream in, byte[] b, int off, int len) throws IOException { + int total = 0; + while (true) { + int got = in.read(b, off + total, len - total); + if (got < 0) { + return (total == 0) ? -1 : total; + } + total += got; + if (total == len) { + return total; + } + } + } - private static final POILogger logger = POILogFactory - .getLogger( IOUtils.class ); - - private IOUtils() { - // no instances of this class - } - - /** - * Reads all the data from the input stream, and returns the bytes read. - */ - public static byte[] toByteArray(InputStream stream) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - byte[] buffer = new byte[4096]; - int read = 0; - while (read != -1) { - read = stream.read(buffer); - if (read > 0) { - baos.write(buffer, 0, read); - } - } - - return baos.toByteArray(); - } - - /** - * Returns an array (that shouldn't be written to!) of the - * ByteBuffer. Will be of the requested length, or possibly - * longer if that's easier. - */ - public static byte[] toByteArray(ByteBuffer buffer, int length) { - if(buffer.hasArray() && buffer.arrayOffset() == 0) { - // The backing array should work out fine for us - return buffer.array(); - } - - byte[] data = new byte[length]; - buffer.get(data); - return data; - } - - /** - * Helper method, just calls <tt>readFully(in, b, 0, b.length)</tt> - */ - public static int readFully(InputStream in, byte[] b) throws IOException { - return readFully(in, b, 0, b.length); - } - - /** - * Same as the normal <tt>in.read(b, off, len)</tt>, but tries to ensure - * that the entire len number of bytes is read. - * <p> - * If the end of file is reached before any bytes are read, returns -1. If - * the end of the file is reached after some bytes are read, returns the - * number of bytes read. If the end of the file isn't reached before len - * bytes have been read, will return len bytes. - */ - public static int readFully(InputStream in, byte[] b, int off, int len) throws IOException { - int total = 0; - while (true) { - int got = in.read(b, off + total, len - total); - if (got < 0) { - return (total == 0) ? -1 : total; - } - total += got; - if (total == len) { - return total; - } - } - } - - /** - * Same as the normal <tt>channel.read(b)</tt>, but tries to ensure - * that the entire len number of bytes is read. - * <p> - * If the end of file is reached before any bytes are read, returns -1. If - * the end of the file is reached after some bytes are read, returns the - * number of bytes read. If the end of the file isn't reached before len - * bytes have been read, will return len bytes. - */ - public static int readFully(ReadableByteChannel channel, ByteBuffer b) throws IOException { - int total = 0; - while (true) { - int got = channel.read(b); - if (got < 0) { - return (total == 0) ? -1 : total; - } - total += got; - if (total == b.capacity() || b.position() == b.capacity()) { - return total; - } - } - } - - /** - * Copies all the data from the given InputStream to the OutputStream. It - * leaves both streams open, so you will still need to close them once done. - */ - public static void copy(InputStream inp, OutputStream out) throws IOException { - byte[] buff = new byte[4096]; - int count; - while ((count = inp.read(buff)) != -1) { - if (count > 0) { - out.write(buff, 0, count); - } - } - } + /** + * Same as the normal <tt>channel.read(b)</tt>, but tries to ensure + * that the entire len number of bytes is read. + * <p> + * If the end of file is reached before any bytes are read, returns -1. If + * the end of the file is reached after some bytes are read, returns the + * number of bytes read. If the end of the file isn't reached before len + * bytes have been read, will return len bytes. + */ + public static int readFully(ReadableByteChannel channel, ByteBuffer b) throws IOException { + int total = 0; + while (true) { + int got = channel.read(b); + if (got < 0) { + return (total == 0) ? -1 : total; + } + total += got; + if (total == b.capacity() || b.position() == b.capacity()) { + return total; + } + } + } + + /** + * Copies all the data from the given InputStream to the OutputStream. It + * leaves both streams open, so you will still need to close them once done. + */ + public static void copy(InputStream inp, OutputStream out) throws IOException { + byte[] buff = new byte[4096]; + int count; + while ((count = inp.read(buff)) != -1) { + if (count > 0) { + out.write(buff, 0, count); + } + } + } public static long calculateChecksum(byte[] data) { Checksum sum = new CRC32(); @@ -150,14 +179,10 @@ public final class IOUtils { * @param closeable * resource to close */ - public static void closeQuietly( final Closeable closeable ) - { - try - { + public static void closeQuietly( final Closeable closeable ) { + try { closeable.close(); - } - catch ( Exception exc ) - { + } catch ( Exception exc ) { logger.log( POILogger.ERROR, "Unable to close resource: " + exc, exc ); } |