/*
* 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.
/**
* 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
/**
* 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 length
of bytes from in
. Note that this method is safe to be called with unknown large 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.
Params: - is – input stream, must not be null
- length – number of bytes to read
Throws: - EOFException – if there are not enough bytes in the stream
- IOException – if an I/O error occurs or
length
is negative - OutOfMemoryError – if an array of the required size cannot be
allocated.
Returns: bytes read
/**
* Read exactly {@code length} of bytes from {@code in}.
*
* <p> 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.
Params: - is – input stream, must not be null
Throws: - IOException – if an I/O error occurs
- OutOfMemoryError – if an array of the required size cannot be
allocated.
Implementation Requirements: This method invokes readNBytes(InputStream)
with a length of Integer.MAX_VALUE
. Returns: a byte array containing the bytes read from this input stream Since: 1.9
/**
* 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.
*
* <p> When this stream reaches end of stream, further invocations of this
* method will return an empty byte array.
*
* <p> 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.
*
* <p> The behavior for the case where the input stream is <i>asynchronously
* closed</i>, or the thread interrupted during the read, is highly input
* stream specific, and therefore not specified.
*
* <p> 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 len
is zero, then no bytes are read and an empty byte array is returned. Otherwise, up to len
bytes are read from the stream. Fewer than 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 len
. Therefore, the method may be safely called with very large values of 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.
Params: - is – input stream, must not be null
- len – the maximum number of bytes to read
Throws: - IllegalArgumentException – if
length
is negative - IOException – if an I/O error occurs
- OutOfMemoryError – if an array of the required size cannot be
allocated.
Implementation Note: The number of bytes allocated to read data from this stream and return the result is bounded by 2*(long)len
, inclusive. Returns: a byte array containing the bytes read from this input stream Since: 11
/**
* 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.
*
* <p> 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.
*
* <p> When this stream reaches end of stream, further invocations of this
* method will return an empty byte array.
*
* <p> 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.
*
* <p> The behavior for the case where the input stream is <i>asynchronously
* closed</i>, or the thread interrupted during the read, is highly input
* stream specific, and therefore not specified.
*
* <p> 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<byte[]> bufs = null;
byte[] result = null;
int total = 0;
int remaining = len;
int n;
do {
byte[] buf = new byte[Math.min(remaining, DEFAULT_BUFFER_SIZE)];
int nread = 0;
// read to EOF which may read more or less than buffer size
while ((n = is.read(buf, nread,
Math.min(buf.length - nread, remaining))) > 0) {
nread += n;
remaining -= n;
}
if (nread > 0) {
if (MAX_BUFFER_SIZE - total < nread) {
throw new OutOfMemoryError("Required array size too large");
}
total += nread;
if (result == null) {
result = buf;
} else {
if (bufs == null) {
bufs = new ArrayList<>();
bufs.add(result);
}
bufs.add(buf);
}
}
// if the last call to read returned -1 or the number of bytes
// requested have been read then break
} while (n >= 0 && remaining > 0);
if (bufs == null) {
if (result == null) {
return new byte[0];
}
return result.length == total ?
result : Arrays.copyOf(result, total);
}
result = new byte[total];
int offset = 0;
remaining = total;
for (byte[] b : bufs) {
int count = Math.min(b.length, remaining);
System.arraycopy(b, 0, result, offset, count);
offset += count;
remaining -= count;
}
return result;
}
Reads the requested number of bytes from the input stream into the given byte array. This method blocks until len
bytes of input data have been read, end of stream is detected, or an exception is thrown. The number of bytes actually read, possibly zero, is returned. This method does not close the input stream. In the case where end of stream is reached before 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 len
is zero, then no bytes are read and 0
is returned; otherwise, there is an attempt to read up to len
bytes.
The first byte read is stored into element b[off]
, the next one in to b[off+1]
, and so on. The number of bytes read is, at most, equal to len
. Let k be the number of bytes actually read; these bytes will be stored in elements b[off]
through b[off+
k-1]
, leaving elements b[off+
k ]
through 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 b
have been updated with data from the input stream. Consequently the input stream and b
may be in an inconsistent state. It is strongly recommended that the stream be promptly closed if an I/O error occurs.
Params: - is – input stream, must not be null
- b – the byte array into which the data is read
- off – the start offset in
b
at which the data is written - len – the maximum number of bytes to read
Throws: - IOException – if an I/O error occurs
- NullPointerException – if
b
is null
- IndexOutOfBoundsException – If
off
is negative, len
is negative, or len
is greater than b.length - off
Returns: the actual number of bytes read into the buffer Since: 1.9
/**
* Reads the requested number of bytes from the input stream into the given
* byte array. This method blocks until {@code len} bytes of input data have
* been read, end of stream is detected, or an exception is thrown. The
* number of bytes actually read, possibly zero, is returned. This method
* does not close the input stream.
*
* <p> 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.
*
* <p> 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.
*
* <p> 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 <i>k</i> be the number of bytes actually
* read; these bytes will be stored in elements {@code b[off]} through
* {@code b[off+}<i>k</i>{@code -1]}, leaving elements {@code b[off+}<i>k</i>
* {@code ]} through {@code b[off+len-1]} unaffected.
*
* <p> The behavior for the case where the input stream is <i>asynchronously
* closed</i>, or the thread interrupted during the read, is highly input
* stream specific, and therefore not specified.
*
* <p> 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 sun.misc.IOUtils.readFully
following its removal in JDK-8231139. Read up to length
of bytes from in
until EOF is detected. Params: - is – input stream, must not be null
- length – number of bytes to read
- readAll – if true, an EOFException will be thrown if not enough
bytes are read.
Throws: - EOFException – if there are not enough bytes in the stream
- IOException – if an I/O error occurs or
length
is negative - OutOfMemoryError – if an array of the required size cannot be
allocated.
Returns: bytes read
/**
* 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);
}
}
}