/* * $Id$ * * Copyright (c) 2007-2010 by Joel Uckelman * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License (LGPL) as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, copies are available * at http://www.opensource.org. */ package VASSAL.tools.io; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.OutputStream; import java.nio.channels.FileChannel; import java.util.zip.ZipFile; import javax.imageio.stream.ImageInputStream; /** * General I/O stream manipulation utilities. This class provides static * utility methods to reduce boilerplate I/O code. * * @author Joel Uckelman * @since 3.1.0 */ public class IOUtils extends org.apache.commons.io.IOUtils { protected IOUtils() {} /** * Copies bytes from a <code>FileInputStream</code> to a * <code>FileOutputStream</code>. * * This method uses channels. The input file should not be written * to during the copy. * * @param in the source * @param out the destination * @throws IOException if one occurs while reading or writing */ public static int copy(FileInputStream in, FileOutputStream out) throws IOException { final long count = copyLarge(in, out); return count > Integer.MAX_VALUE ? -1 : (int) count; } /** * Copies bytes from a large (over 2GB) <code>FileInputStream</code> to a * <code>FileOutputStream</code>. * * This method uses channels. The input file should not be written * to during the copy. * * @param in the source * @param out the destination * @throws IOException if one occurs while reading or writing */ public static long copyLarge(FileInputStream in, FileOutputStream out) throws IOException { final FileChannel inc = in.getChannel(); return inc.transferTo(0L, inc.size(), out.getChannel()); } /** * Copies bytes from an <code>InputStream</code> to an * <code>OutputStream</code> via a <code>byte</code> buffer. This * method buffers input internally, so the input stream should not * be a <code>BufferedInputStream</code>. * * @param in the source * @param out the destination * @param buffer the buffer * @return the number of bytes copied * @throws IOException if one occurs while reading or writing */ public static int copy(InputStream in, OutputStream out, byte[] buffer) throws IOException { final long count = copyLarge(in, out, buffer); return count > Integer.MAX_VALUE ? -1 : (int) count; } /** * Copies bytes from a large (over 2GB) <code>InputStream</code> to an * <code>OutputStream</code> via a <code>byte</code> buffer. This * method buffers input internally, so the input stream should not * be a <code>BufferedInputStream</code>. * * @param in the source * @param out the destination * @param buffer the buffer * @return the number of bytes copied * @throws IOException if one occurs while reading or writing */ public static long copyLarge(InputStream in, OutputStream out, byte[] buffer) throws IOException { long count = 0; int n = 0; while ((n = in.read(buffer)) != -1) { out.write(buffer, 0, n); count += n; } return count; } /** * Close an {@link ObjectInput} unconditionally. Equivalent to * calling <code>o.close()</code> when <code>o</code> is nonnull. * {@link IOException}s are swallowed, as there is generally * nothing that can be done about exceptions on closing. * * @param o a (possibly <code>null</code>) <code>ObjectInput</code> */ public static void closeQuietly(ObjectInput o) { if (o == null) return; try { o.close(); } catch (IOException e) { // ignore } } /** * Close an {@link ObjectOutput} unconditionally. Equivalent to * calling <code>o.close()</code> when <code>o</code> is nonnull. * {@link IOException}s are swallowed, as there is generally * nothing that can be done about exceptions on closing. * * @param o a (possibly <code>null</code>) <code>ObjectOutput</code> */ public static void closeQuietly(ObjectOutput o) { if (o == null) return; try { o.close(); } catch (IOException e) { // ignore } } /** * Close a {@link ZipFile} unconditionally. Equivalent to * calling <code>z.close()</code> when <code>z</code> is nonnull. * {@link IOException}s are swallowed, as there is generally * nothing that can be done about exceptions on closing. * * @param z a (possibly <code>null</code>) <code>ZipFile</code> */ // Why doesn't ZipFile implement Closeable? Argh! public static void closeQuietly(ZipFile z) { if (z == null) return; try { z.close(); } catch (IOException e) { // ignore } } /** * Close an {@link ImageInputStream} unconditionally. Equivalent to * calling <code>s.close()</code> when <code>s</code> is nonnull. * {@link IOException}s are quietly logged, as there is generally * nothing that can be done about exceptions on closing. * * @param s a (possibly <code>null</code>) <code>ImageInputStream</code> */ // Why doesn't ImageInputStream implement Closeable? Argh! public static void closeQuietly(ImageInputStream s) { if (s == null) return; try { s.close(); } catch (IOException e) { // ignore // Note that ImageInputStreamImpl.close() rather ridiculously throws // an IOException if the stream is already closed. This is always done // via ImageInputStreamImpl.checkClosed(). } } }