/** * Licensed under the GNU LGPL v.2.1 or later. */ package info.freelibrary.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.jar.JarFile; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Utilities for working with IO streams. * * @author <a href="mailto:ksclarke@ksclarke.io">Kevin S. Clarke</a> */ public class IOUtils { private static final Logger LOGGER = LoggerFactory.getLogger(IOUtils.class); private IOUtils() { } /** * Closes a reader, catching and logging any exceptions. * * @param aReader A supplied reader to close */ public static final void closeQuietly(final Reader aReader) { if (aReader != null) { try { aReader.close(); } catch (final IOException details) { if (LOGGER.isErrorEnabled()) { LOGGER.error(details.getMessage(), details); } } } } /** * Closes a writer, catching and logging any exceptions. * * @param aWriter A supplied writer to close */ public static final void closeQuietly(final Writer aWriter) { if (aWriter != null) { try { aWriter.close(); } catch (final IOException details) { if (LOGGER.isErrorEnabled()) { LOGGER.error(details.getMessage(), details); } } } } /** * Closes an input stream, catching and logging any exceptions. * * @param aInputStream A supplied input stream to close */ public static final void closeQuietly(final InputStream aInputStream) { if (aInputStream != null) { try { aInputStream.close(); } catch (final IOException details) { if (LOGGER.isErrorEnabled()) { LOGGER.error(details.getMessage(), details); } } } } /** * Closes an output stream, catching and logging any exceptions. * * @param aOutputStream A supplied output stream to close */ public static final void closeQuietly(final OutputStream aOutputStream) { if (aOutputStream != null) { try { aOutputStream.close(); } catch (final IOException details) { if (LOGGER.isErrorEnabled()) { LOGGER.error(details.getMessage(), details); } } } } /** * Closes a {@link JarFile}, catching and logging any exceptions. * * @param aJarFile A supplied {@link JarFile} to close */ public static final void closeQuietly(final JarFile aJarFile) { if (aJarFile != null) { try { aJarFile.close(); } catch (final IOException details) { if (LOGGER.isErrorEnabled()) { LOGGER.error(details.getMessage(), details); } } } } /** * Writes from an input stream to an output stream; you're responsible for closing the <code>InputStream</code> and * <code>OutputStream</code>. * * @param aInStream The stream from which to read * @param aOutStream The stream from which to write * @throws IOException If there is trouble reading or writing */ public static final void copyStream(final InputStream aInStream, final OutputStream aOutStream) throws IOException { final BufferedOutputStream outStream = new BufferedOutputStream(aOutStream); final BufferedInputStream inStream = new BufferedInputStream(aInStream); final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); final byte[] buffer = new byte[1024]; int bytesRead = 0; while (true) { bytesRead = inStream.read(buffer); if (bytesRead == -1) { break; } byteStream.write(buffer, 0, bytesRead); } outStream.write(byteStream.toByteArray()); outStream.flush(); } /** * Writes a file to an output stream. You're responsible for closing the <code>OutputStream</code>; the input stream * is closed for you since just a <code>File</code> was passed in. * * @param aFile A file from which to read * @param aOutStream An output stream to which to write * @throws IOException If there is a problem reading or writing */ public static final void copyStream(final File aFile, final OutputStream aOutStream) throws IOException { final FileInputStream input = new FileInputStream(aFile); final FileChannel channel = input.getChannel(); final byte[] buffer = new byte[256 * 1024]; final ByteBuffer byteBuffer = ByteBuffer.wrap(buffer); try { for (int length = 0; (length = channel.read(byteBuffer)) != -1;) { aOutStream.write(buffer, 0, length); byteBuffer.clear(); } } finally { input.close(); } } /** * Reads an InputStream into a byte array. * * @param aInputStream The input stream from which to read * @return The array of bytes * @throws IOException If there is trouble reading from the input stream */ public static final byte[] readBytes(final InputStream aInputStream) throws IOException { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final byte[] buffer = new byte[4096]; int read = 0; while (read != -1) { read = aInputStream.read(buffer); if (read > 0) { baos.write(buffer, 0, read); } } closeQuietly(aInputStream); return baos.toByteArray(); } }