com.feilong.io.IOUtil Maven / Gradle / Ivy
Show all versions of feilong Show documentation
/*
* Copyright (C) 2008 feilong
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.feilong.io;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
/**
* The Class IOUtil.
*
* @author feilong
* @since 3.0.0
*/
public final class IOUtil{
/**
* Represents the end-of-file (or stream).
*/
public static final int EOF = -1;
/**
* The default buffer size ({@value}) to use for
* {@link #copyLarge(InputStream, OutputStream)}
* and
* {@link #copyLarge(Reader, Writer)}
*/
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
/** Don't let anyone instantiate this class. */
private IOUtil(){
//AssertionError不是必须的. 但它可以避免不小心在类的内部调用构造器. 保证该类在任何情况下都不会被实例化.
//see 《Effective Java》 2nd
throw new AssertionError("No " + getClass().getName() + " instances for you!");
}
//---------------------------------------------------------------
/**
* Closes a Closeable
unconditionally.
*
* Equivalent to {@link Closeable#close()}, except any exceptions will be ignored.
*
* This is typically used in finally blocks to ensure that the closeable is closed
* even if an Exception was thrown before the normal close statement was reached.
*
* It should not be used to replace the close statement(s)
* which should be present for the non-exceptional case.
*
* It is only intended to simplify tidying up where normal processing has already failed
* and reporting close failure as well is not necessary or useful.
*
* Example code:
*
*
*
* Closeable closeable = null;
* try {
* closeable = new FileReader("foo.txt");
* // processing using the closeable; may throw an Exception
* closeable.close(); // Normal close - exceptions not ignored
* } catch (Exception e) {
* // error handling
* } finally {
* IOUtil.closeQuietly(closeable); // In case normal close was skipped due to Exception
* }
*
*
* Closing all streams:
*
*
*
* try{
* return IOUtils.copy(inputStream, outputStream);
* }finally{
* IOUtil.closeQuietly(inputStream, outputStream);
* }
*
*
* @param closeables
* the objects to close, may be null or already closed
*
* @see Throwable#addSuppressed(java.lang.Throwable)
*/
public static void closeQuietly(final Closeable...closeables){
if (closeables == null){
return;
}
//---------------------------------------------------------------
for (final Closeable closeable : closeables){
try{
if (closeable != null){
closeable.close();
}
}catch (final IOException ioe){
// ignore
}
}
}
// copy from InputStream
//-----------------------------------------------------------------------
/**
* Copies bytes from an InputStream
to an
* OutputStream
.
*
* This method buffers the input internally, so there is no need to use a
* BufferedInputStream
.
*
* Large streams (over 2GB) will return a bytes copied value of
* -1
after the copy has completed since the correct
* number of bytes cannot be returned as an int. For large streams
* use the copyLarge(InputStream, OutputStream)
method.
*
* @param input
* the InputStream
to read from
* @param output
* the OutputStream
to write to
* @return the number of bytes copied, or -1 if > Integer.MAX_VALUE
* @throws NullPointerException
* if the input or output is null
* @throws IOException
* if an I/O error occurs
* @since 1.1
*/
public static int copy(final InputStream input,final OutputStream output) throws IOException{
final long count = copyLarge(input, output);
if (count > Integer.MAX_VALUE){
return -1;
}
return (int) count;
}
/**
* Copies bytes from an InputStream
to an OutputStream
using an internal buffer of the
* given size.
*
* This method buffers the input internally, so there is no need to use a BufferedInputStream
.
*
*
* @param input
* the InputStream
to read from
* @param output
* the OutputStream
to write to
* @param bufferSize
* the bufferSize used to copy from the input to the output
* @return the number of bytes copied
* @throws NullPointerException
* if the input or output is null
* @throws IOException
* if an I/O error occurs
* @since 2.5
*/
private static long copy(final InputStream input,final OutputStream output,final int bufferSize) throws IOException{
return copyLarge(input, output, new byte[bufferSize]);
}
/**
* Copies bytes from a large (over 2GB) InputStream
to an
* OutputStream
.
*
* This method buffers the input internally, so there is no need to use a
* BufferedInputStream
.
*
* The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
*
* @param input
* the InputStream
to read from
* @param output
* the OutputStream
to write to
* @return the number of bytes copied
* @throws NullPointerException
* if the input or output is null
* @throws IOException
* if an I/O error occurs
* @since 1.3
*/
private static long copyLarge(final InputStream input,final OutputStream output) throws IOException{
return copy(input, output, DEFAULT_BUFFER_SIZE);
}
/**
* Copies bytes from a large (over 2GB) InputStream
to an
* OutputStream
.
*
* This method uses the provided buffer, so there is no need to use a
* BufferedInputStream
.
*
*
* @param input
* the InputStream
to read from
* @param output
* the OutputStream
to write to
* @param buffer
* the buffer to use for the copy
* @return the number of bytes copied
* @throws NullPointerException
* if the input or output is null
* @throws IOException
* if an I/O error occurs
*/
private static long copyLarge(final InputStream input,final OutputStream output,final byte[] buffer) throws IOException{
long count = 0;
int n;
while (EOF != (n = input.read(buffer))){
output.write(buffer, 0, n);
count += n;
}
return count;
}
}