org.apache.tomcat.util.http.fileupload.IOUtils Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.tomcat.util.http.fileupload;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* General IO stream manipulation utilities.
*
* This class provides static utility methods for input/output operations.
*
* - closeQuietly - these methods close a stream ignoring nulls and exceptions
*
- toXxx/read - these methods read data from a stream
*
- write - these methods write data to a stream
*
- copy - these methods copy all the data from one stream to another
*
- contentEquals - these methods compare the content of two streams
*
*
* The byte-to-char methods and char-to-byte methods involve a conversion step.
* Two methods are provided in each case, one that uses the platform default
* encoding and the other which allows you to specify an encoding. You are
* encouraged to always specify an encoding because relying on the platform
* default can lead to unexpected results, for example when moving from
* development to production.
*
* All the methods in this class that read a stream are buffered internally.
* This means that there is no cause to use a BufferedInputStream
* or BufferedReader
. The default buffer size of 4K has been shown
* to be efficient in tests.
*
* Wherever possible, the methods in this class do not flush or close
* the stream. This is to avoid making non-portable assumptions about the
* streams' origin and further use. Thus the caller is still responsible for
* closing streams after use.
*
* Origin of code: Excalibur.
*/
public class IOUtils {
// NOTE: This class is focussed on InputStream, OutputStream, Reader and
// Writer. Each method should take at least one of these as a parameter,
// or return one of them.
private 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;
/**
* Instances should NOT be constructed in standard programming.
*/
public IOUtils() {
super();
}
/**
* Closes a Closeable
unconditionally.
*
* Equivalent to {@link Closeable#close()}, except any exceptions will be ignored. This is typically used in
* finally blocks.
*
* Example code:
*
*
* Closeable closeable = null;
* try {
* closeable = new FileReader("foo.txt");
* // process closeable
* closeable.close();
* } catch (Exception e) {
* // error handling
* } finally {
* IOUtils.closeQuietly(closeable);
* }
*
*
* Closing all streams:
*
*
* try {
* return IOUtils.copy(inputStream, outputStream);
* } finally {
* IOUtils.closeQuietly(inputStream);
* IOUtils.closeQuietly(outputStream);
* }
*
*
* @param closeable
* the objects to close, may be null or already closed
* @since 2.0
*/
public static void closeQuietly(final Closeable closeable) {
try {
if (closeable != null) {
closeable.close();
}
} catch (final IOException ioe) {
// ignore
}
}
// copy from InputStream
//-----------------------------------------------------------------------
/**
* Copy 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(InputStream input, OutputStream output) throws IOException {
long count = copyLarge(input, output);
if (count > Integer.MAX_VALUE) {
return -1;
}
return (int) count;
}
/**
* Copy 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
*/
public static long copyLarge(InputStream input, OutputStream output)
throws IOException {
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
long count = 0;
int n = 0;
while (EOF != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
}