| Streams.java |
/***************************************
* *
* JBoss: The OpenSource J2EE WebOS *
* *
* Distributable under LGPL license. *
* See terms of license at gnu.org. *
* *
***************************************/
package org.jboss.util.stream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import org.jboss.util.ThrowableHandler;
import org.jboss.logging.Logger;
/**
* A collection of stream related utility methods.
*
* <p>Exceptions that are thrown and not explicitly declared are given to
* the {@link ThrowableHandler} for further processing.
*
* @version <tt>$Revision: 1.4 $</tt>
* @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
*/
public final class Streams
{
private static final Logger log = Logger.getLogger(Streams.class);
/////////////////////////////////////////////////////////////////////////
// Closing //
/////////////////////////////////////////////////////////////////////////
/**
* Attempt to close an <tt>InputStream</tt>.
*
* @param stream <tt>InputStream</tt> to attempt to close.
* @return <tt>True</tt> if stream was closed (or stream was null),
* or <tt>false</tt> if an exception was thrown.
*/
public static boolean close(final InputStream stream) {
// do not attempt to close null stream, but return sucess
if (stream == null) {
return true;
}
boolean success = true;
try {
stream.close();
}
catch (IOException e) {
success = false;
ThrowableHandler.add(e);
}
return success;
}
/**
* Attempt to close an <tt>OutputStream</tt>.
*
* @param stream <tt>OutputStream</tt> to attempt to close.
* @return <tt>True</tt> if stream was closed (or stream was null),
* or <tt>false</tt> if an exception was thrown.
*/
public static boolean close(final OutputStream stream) {
// do not attempt to close null stream, but return sucess
if (stream == null) {
return true;
}
boolean success = true;
try {
stream.close();
}
catch (IOException e) {
success = false;
ThrowableHandler.add(e);
}
return success;
}
/**
* Attempt to close an <tt>InputStream</tt> or <tt>OutputStream</tt>.
*
* @param stream Stream to attempt to close.
* @return <tt>True</tt> if stream was closed (or stream was null),
* or <tt>false</tt> if an exception was thrown.
*
* @throws IllegalArgumentException Stream is not an <tt>InputStream</tt>
* or <tt>OuputStream</tt>.
*/
public static boolean close(final Object stream) {
boolean success = false;
if (stream instanceof InputStream) {
success = close((InputStream)stream);
}
else if (stream instanceof OutputStream) {
success = close((OutputStream)stream);
}
else {
throw new IllegalArgumentException
("stream is not an InputStream or OutputStream");
}
return success;
}
/**
* Attempt to close an array of <tt>InputStream</tt>s.
*
* @param streams Array of <tt>InputStream</tt>s to attempt to close.
* @return <tt>True</tt> if all streams were closed, or <tt>false</tt>
* if an exception was thrown.
*/
public static boolean close(final InputStream[] streams) {
boolean success = true;
for (int i=0; i<streams.length; i++) {
boolean rv = close(streams[i]);
if (!rv) success = false;
}
return success;
}
/**
* Attempt to close an array of <tt>OutputStream</tt>s.
*
* @param streams Array of <tt>OutputStream</tt>s to attempt to close.
* @return <tt>True</tt> if all streams were closed, or <tt>false</tt>
* if an exception was thrown.
*/
public static boolean close(final OutputStream[] streams) {
boolean success = true;
for (int i=0; i<streams.length; i++) {
boolean rv = close(streams[i]);
if (!rv) success = false;
}
return success;
}
/**
* Attempt to close an array of <tt>InputStream</tt>a and/or
* <tt>OutputStream</tt>s.
*
* @param streams Array of streams to attempt to close.
* @return <tt>True</tt> if all streams were closed, or <tt>false</tt>
* if an exception was thrown.
*
* @throws IllegalArgumentException Stream is not an <tt>InputStream</tt>
* or <tt>OuputStream</tt>. Closing
* stops at the last valid stream
* object in this case.
*/
public static boolean close(final Object[] streams) {
boolean success = true;
for (int i=0; i<streams.length; i++) {
boolean rv = close(streams[i]);
if (!rv) success = false;
}
return success;
}
/**
* Attempt to flush and close an <tt>OutputStream</tt>.
*
* @param stream <tt>OutputStream</tt> to attempt to flush and close.
* @return <tt>True</tt> if stream was flushed and closed, or
* <tt>false</tt> if an exception was thrown.
*/
public static boolean fclose(final OutputStream stream) {
return flush(stream) && close(stream);
}
/**
* Attempt to flush and close an array of <tt>OutputStream</tt>s.
*
* @param streams <tt>OutputStream</tt>s to attempt to flush and close.
* @return <tt>True</tt> if all streams were flushed and closed,
* or <tt>false</tt> if an exception was thrown.
*/
public static boolean fclose(final OutputStream[] streams) {
boolean success = true;
for (int i=0; i<streams.length; i++) {
boolean rv = fclose(streams[i]);
if (!rv) success = false;
}
return success;
}
/////////////////////////////////////////////////////////////////////////
// Flushing //
/////////////////////////////////////////////////////////////////////////
/**
* Attempt to flush an <tt>OutputStream</tt>.
*
* @param stream <tt>OutputStream</tt> to attempt to flush.
* @return <tt>True</tt> if stream was flushed (or stream was null),
* or <tt>false</tt> if an exception was thrown.
*/
public static boolean flush(final OutputStream stream) {
// do not attempt to close null stream, but return sucess
if (stream == null) {
return true;
}
boolean success = true;
try {
stream.flush();
}
catch (IOException e) {
success = false;
ThrowableHandler.add(e);
}
return success;
}
/**
* Attempt to flush an array of <tt>OutputStream</tt>s.
*
* @param streams <tt>OutputStream</tt>s to attempt to flush.
* @return <tt>True</tt> if all streams were flushed, or <tt>false</tt>
* if an exception was thrown.
*/
public static boolean flush(final OutputStream[] streams) {
boolean success = true;
for (int i=0; i<streams.length; i++) {
boolean rv = flush(streams[i]);
if (!rv) success = false;
}
return success;
}
/////////////////////////////////////////////////////////////////////////
// Misc //
/////////////////////////////////////////////////////////////////////////
/** The default buffer size that will be used for buffered operations. */
public static final int DEFAULT_BUFFER_SIZE = 2048;
/**
* Copy all of the bytes from the input stream to the output stream.
*
* @param input Stream to read bytes from.
* @param output Stream to write bytes to.
* @param buffer The buffer to use while copying.
* @return The total number of bytes copied.
*
* @throws IOException Failed to copy bytes.
*/
public static long copy(final InputStream input,
final OutputStream output,
final byte buffer[])
throws IOException
{
long total = 0;
int read;
boolean trace = log.isTraceEnabled();
if (trace) {
log.trace("copying " + input + " to " + output + " with buffer size: " + buffer.length);
}
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
total += read;
if (trace) {
log.trace("bytes read: " + read + "; total bytes read: " + total);
}
}
return total;
}
/**
* Copy all of the bytes from the input stream to the output stream.
*
* @param input Stream to read bytes from.
* @param output Stream to write bytes to.
* @param size The size of the buffer to use while copying.
* @return The total number of bytes copied.
*
* @throws IOException Failed to copy bytes.
*/
public static long copy(final InputStream input,
final OutputStream output,
final int size)
throws IOException
{
return copy(input, output, new byte[size]);
}
/**
* Copy all of the bytes from the input stream to the output stream.
*
* @param input Stream to read bytes from.
* @param output Stream to write bytes to.
* @return The total number of bytes copied.
*
* @throws IOException Failed to copy bytes.
*/
public static long copy(final InputStream input,
final OutputStream output)
throws IOException
{
return copy(input, output, DEFAULT_BUFFER_SIZE);
}
/**
* Copy all of the bytes from the input stream to the output stream
* wrapping streams in buffers as needed.
*
* @param input Stream to read bytes from.
* @param output Stream to write bytes to.
* @return The total number of bytes copied.
*
* @throws IOException Failed to copy bytes.
*/
public static long copyb(InputStream input,
OutputStream output)
throws IOException
{
if (!(input instanceof BufferedInputStream)) {
input = new BufferedInputStream(input);
}
if (!(output instanceof BufferedOutputStream)) {
output = new BufferedOutputStream(output);
}
long bytes = copy(input, output, DEFAULT_BUFFER_SIZE);
output.flush();
return bytes;
}
/**
* Copy a limited number of bytes from the input stream to the
* output stream.
*
* @param input Stream to read bytes from.
* @param output Stream to write bytes to.
* @param buffer The buffer to use while copying.
* @param length The maximum number of bytes to copy.
* @return The total number of bytes copied.
*
* @throws IOException Failed to copy bytes.
*/
public static long copySome(final InputStream input,
final OutputStream output,
final byte buffer[],
final long length)
throws IOException
{
long total = 0;
int read;
int readLength;
boolean trace = log.isTraceEnabled();
// setup the initial readLength, if length is less than the buffer
// size, then we only want to read that much
readLength = Math.min((int)length, buffer.length);
if (trace) {
log.trace("initial read length: " + readLength);
}
while (readLength != 0 && (read = input.read(buffer, 0, readLength)) != -1)
{
if (trace) log.trace("read bytes: " + read);
output.write(buffer, 0, read);
total += read;
if (trace) log.trace("total bytes read: " + total);
// update the readLength
readLength = Math.min((int)(length - total), buffer.length);
if (trace) log.trace("next read length: " + readLength);
}
return total;
}
/**
* Copy a limited number of bytes from the input stream to the
* output stream.
*
* @param input Stream to read bytes from.
* @param output Stream to write bytes to.
* @param size The size of the buffer to use while copying.
* @param length The maximum number of bytes to copy.
* @return The total number of bytes copied.
*
* @throws IOException Failed to copy bytes.
*/
public static long copySome(final InputStream input,
final OutputStream output,
final int size,
final long length)
throws IOException
{
return copySome(input, output, new byte[size], length);
}
/**
* Copy a limited number of bytes from the input stream to the
* output stream.
*
* @param input Stream to read bytes from.
* @param output Stream to write bytes to.
* @param length The maximum number of bytes to copy.
* @return The total number of bytes copied.
*
* @throws IOException Failed to copy bytes.
*/
public static long copySome(final InputStream input,
final OutputStream output,
final long length)
throws IOException
{
return copySome(input, output, DEFAULT_BUFFER_SIZE, length);
}
}
| Streams.java |