/* * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /** * IOUtils: A collection of IO-related public static methods. */ package sun.misc; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; public class IOUtils { private static final int DEFAULT_BUFFER_SIZE = 8192; /** * The maximum size of array to allocate. * Some VMs reserve some header words in an array. * Attempts to allocate larger arrays may result in * OutOfMemoryError: Requested array size exceeds VM limit */ private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; /** * Read exactly {@code length} of bytes from {@code in}. * *
Note that this method is safe to be called with unknown large * {@code length} argument. The memory used is proportional to the * actual bytes available. An exception is thrown if there are not * enough bytes in the stream. * * @param is input stream, must not be null * @param length number of bytes to read * @return bytes read * @throws EOFException if there are not enough bytes in the stream * @throws IOException if an I/O error occurs or {@code length} is negative * @throws OutOfMemoryError if an array of the required size cannot be * allocated. */ public static byte[] readExactlyNBytes(InputStream is, int length) throws IOException { if (length < 0) { throw new IOException("length cannot be negative: " + length); } byte[] data = readNBytes(is, length); if (data.length < length) { throw new EOFException(); } return data; } /** * Reads all remaining bytes from the input stream. This method blocks until * all remaining bytes have been read and end of stream is detected, or an * exception is thrown. This method does not close the input stream. * *
When this stream reaches end of stream, further invocations of this * method will return an empty byte array. * *
Note that this method is intended for simple cases where it is * convenient to read all bytes into a byte array. It is not intended for * reading input streams with large amounts of data. * *
The behavior for the case where the input stream is asynchronously * closed, or the thread interrupted during the read, is highly input * stream specific, and therefore not specified. * *
If an I/O error occurs reading from the input stream, then it may do * so after some, but not all, bytes have been read. Consequently the input * stream may not be at end of stream and may be in an inconsistent state. * It is strongly recommended that the stream be promptly closed if an I/O * error occurs. * * @implSpec * This method invokes {@link #readNBytes(int)} with a length of * {@link Integer#MAX_VALUE}. * * @param is input stream, must not be null * @return a byte array containing the bytes read from this input stream * @throws IOException if an I/O error occurs * @throws OutOfMemoryError if an array of the required size cannot be * allocated. * * @since 1.9 */ public static byte[] readAllBytes(InputStream is) throws IOException { return readNBytes(is, Integer.MAX_VALUE); } /** * Reads up to a specified number of bytes from the input stream. This * method blocks until the requested number of bytes have been read, end * of stream is detected, or an exception is thrown. This method does not * close the input stream. * *
The length of the returned array equals the number of bytes read * from the stream. If {@code len} is zero, then no bytes are read and * an empty byte array is returned. Otherwise, up to {@code len} bytes * are read from the stream. Fewer than {@code len} bytes may be read if * end of stream is encountered. * *
When this stream reaches end of stream, further invocations of this * method will return an empty byte array. * *
Note that this method is intended for simple cases where it is * convenient to read the specified number of bytes into a byte array. The * total amount of memory allocated by this method is proportional to the * number of bytes read from the stream which is bounded by {@code len}. * Therefore, the method may be safely called with very large values of * {@code len} provided sufficient memory is available. * *
The behavior for the case where the input stream is asynchronously * closed, or the thread interrupted during the read, is highly input * stream specific, and therefore not specified. * *
If an I/O error occurs reading from the input stream, then it may do
* so after some, but not all, bytes have been read. Consequently the input
* stream may not be at end of stream and may be in an inconsistent state.
* It is strongly recommended that the stream be promptly closed if an I/O
* error occurs.
*
* @implNote
* The number of bytes allocated to read data from this stream and return
* the result is bounded by {@code 2*(long)len}, inclusive.
*
* @param is input stream, must not be null
* @param len the maximum number of bytes to read
* @return a byte array containing the bytes read from this input stream
* @throws IllegalArgumentException if {@code length} is negative
* @throws IOException if an I/O error occurs
* @throws OutOfMemoryError if an array of the required size cannot be
* allocated.
*
* @since 11
*/
public static byte[] readNBytes(InputStream is, int len) throws IOException {
if (len < 0) {
throw new IllegalArgumentException("len < 0");
}
List In the case where end of stream is reached before {@code len} bytes
* have been read, then the actual number of bytes read will be returned.
* When this stream reaches end of stream, further invocations of this
* method will return zero.
*
* If {@code len} is zero, then no bytes are read and {@code 0} is
* returned; otherwise, there is an attempt to read up to {@code len} bytes.
*
* The first byte read is stored into element {@code b[off]}, the next
* one in to {@code b[off+1]}, and so on. The number of bytes read is, at
* most, equal to {@code len}. Let k be the number of bytes actually
* read; these bytes will be stored in elements {@code b[off]} through
* {@code b[off+}k{@code -1]}, leaving elements {@code b[off+}k
* {@code ]} through {@code b[off+len-1]} unaffected.
*
* The behavior for the case where the input stream is asynchronously
* closed, or the thread interrupted during the read, is highly input
* stream specific, and therefore not specified.
*
* If an I/O error occurs reading from the input stream, then it may do
* so after some, but not all, bytes of {@code b} have been updated with
* data from the input stream. Consequently the input stream and {@code b}
* may be in an inconsistent state. It is strongly recommended that the
* stream be promptly closed if an I/O error occurs.
*
* @param is input stream, must not be null
* @param b the byte array into which the data is read
* @param off the start offset in {@code b} at which the data is written
* @param len the maximum number of bytes to read
* @return the actual number of bytes read into the buffer
* @throws IOException if an I/O error occurs
* @throws NullPointerException if {@code b} is {@code null}
* @throws IndexOutOfBoundsException If {@code off} is negative, {@code len}
* is negative, or {@code len} is greater than {@code b.length - off}
*
* @since 1.9
*/
public static int readNBytes(InputStream is, byte[] b, int off, int len) throws IOException {
Objects.requireNonNull(b);
if (off < 0 || len < 0 || len > b.length - off)
throw new IndexOutOfBoundsException();
int n = 0;
while (n < len) {
int count = is.read(b, off + n, len - n);
if (count < 0)
break;
n += count;
}
return n;
}
/**
* Compatibility wrapper for third party users of
* {@code sun.misc.IOUtils.readFully} following its
* removal in JDK-8231139.
*
* Read up to {@code length} of bytes from {@code in}
* until EOF is detected.
*
* @param is input stream, must not be null
* @param length number of bytes to read
* @param readAll if true, an EOFException will be thrown if not enough
* bytes are read.
* @return bytes read
* @throws EOFException if there are not enough bytes in the stream
* @throws IOException if an I/O error occurs or {@code length} is negative
* @throws OutOfMemoryError if an array of the required size cannot be
* allocated.
*/
public static byte[] readFully(InputStream is, int length, boolean readAll)
throws IOException {
if (length < 0) {
throw new IOException("length cannot be negative: " + length);
}
if (readAll) {
return readExactlyNBytes(is, length);
} else {
return readNBytes(is, length);
}
}
}