Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/misc/IOUtils.java
38829 views
/*1* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/**26* IOUtils: A collection of IO-related public static methods.27*/2829package sun.misc;3031import java.io.EOFException;32import java.io.IOException;33import java.io.InputStream;3435import java.util.ArrayList;36import java.util.Arrays;37import java.util.List;38import java.util.Objects;3940public class IOUtils {4142private static final int DEFAULT_BUFFER_SIZE = 8192;4344/**45* The maximum size of array to allocate.46* Some VMs reserve some header words in an array.47* Attempts to allocate larger arrays may result in48* OutOfMemoryError: Requested array size exceeds VM limit49*/50private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;5152/**53* Read exactly {@code length} of bytes from {@code in}.54*55* <p> Note that this method is safe to be called with unknown large56* {@code length} argument. The memory used is proportional to the57* actual bytes available. An exception is thrown if there are not58* enough bytes in the stream.59*60* @param is input stream, must not be null61* @param length number of bytes to read62* @return bytes read63* @throws EOFException if there are not enough bytes in the stream64* @throws IOException if an I/O error occurs or {@code length} is negative65* @throws OutOfMemoryError if an array of the required size cannot be66* allocated.67*/68public static byte[] readExactlyNBytes(InputStream is, int length)69throws IOException {70if (length < 0) {71throw new IOException("length cannot be negative: " + length);72}73byte[] data = readNBytes(is, length);74if (data.length < length) {75throw new EOFException();76}77return data;78}7980/**81* Reads all remaining bytes from the input stream. This method blocks until82* all remaining bytes have been read and end of stream is detected, or an83* exception is thrown. This method does not close the input stream.84*85* <p> When this stream reaches end of stream, further invocations of this86* method will return an empty byte array.87*88* <p> Note that this method is intended for simple cases where it is89* convenient to read all bytes into a byte array. It is not intended for90* reading input streams with large amounts of data.91*92* <p> The behavior for the case where the input stream is <i>asynchronously93* closed</i>, or the thread interrupted during the read, is highly input94* stream specific, and therefore not specified.95*96* <p> If an I/O error occurs reading from the input stream, then it may do97* so after some, but not all, bytes have been read. Consequently the input98* stream may not be at end of stream and may be in an inconsistent state.99* It is strongly recommended that the stream be promptly closed if an I/O100* error occurs.101*102* @implSpec103* This method invokes {@link #readNBytes(int)} with a length of104* {@link Integer#MAX_VALUE}.105*106* @param is input stream, must not be null107* @return a byte array containing the bytes read from this input stream108* @throws IOException if an I/O error occurs109* @throws OutOfMemoryError if an array of the required size cannot be110* allocated.111*112* @since 1.9113*/114public static byte[] readAllBytes(InputStream is) throws IOException {115return readNBytes(is, Integer.MAX_VALUE);116}117118/**119* Reads up to a specified number of bytes from the input stream. This120* method blocks until the requested number of bytes have been read, end121* of stream is detected, or an exception is thrown. This method does not122* close the input stream.123*124* <p> The length of the returned array equals the number of bytes read125* from the stream. If {@code len} is zero, then no bytes are read and126* an empty byte array is returned. Otherwise, up to {@code len} bytes127* are read from the stream. Fewer than {@code len} bytes may be read if128* end of stream is encountered.129*130* <p> When this stream reaches end of stream, further invocations of this131* method will return an empty byte array.132*133* <p> Note that this method is intended for simple cases where it is134* convenient to read the specified number of bytes into a byte array. The135* total amount of memory allocated by this method is proportional to the136* number of bytes read from the stream which is bounded by {@code len}.137* Therefore, the method may be safely called with very large values of138* {@code len} provided sufficient memory is available.139*140* <p> The behavior for the case where the input stream is <i>asynchronously141* closed</i>, or the thread interrupted during the read, is highly input142* stream specific, and therefore not specified.143*144* <p> If an I/O error occurs reading from the input stream, then it may do145* so after some, but not all, bytes have been read. Consequently the input146* stream may not be at end of stream and may be in an inconsistent state.147* It is strongly recommended that the stream be promptly closed if an I/O148* error occurs.149*150* @implNote151* The number of bytes allocated to read data from this stream and return152* the result is bounded by {@code 2*(long)len}, inclusive.153*154* @param is input stream, must not be null155* @param len the maximum number of bytes to read156* @return a byte array containing the bytes read from this input stream157* @throws IllegalArgumentException if {@code length} is negative158* @throws IOException if an I/O error occurs159* @throws OutOfMemoryError if an array of the required size cannot be160* allocated.161*162* @since 11163*/164public static byte[] readNBytes(InputStream is, int len) throws IOException {165if (len < 0) {166throw new IllegalArgumentException("len < 0");167}168169List<byte[]> bufs = null;170byte[] result = null;171int total = 0;172int remaining = len;173int n;174do {175byte[] buf = new byte[Math.min(remaining, DEFAULT_BUFFER_SIZE)];176int nread = 0;177178// read to EOF which may read more or less than buffer size179while ((n = is.read(buf, nread,180Math.min(buf.length - nread, remaining))) > 0) {181nread += n;182remaining -= n;183}184185if (nread > 0) {186if (MAX_BUFFER_SIZE - total < nread) {187throw new OutOfMemoryError("Required array size too large");188}189total += nread;190if (result == null) {191result = buf;192} else {193if (bufs == null) {194bufs = new ArrayList<>();195bufs.add(result);196}197bufs.add(buf);198}199}200// if the last call to read returned -1 or the number of bytes201// requested have been read then break202} while (n >= 0 && remaining > 0);203204if (bufs == null) {205if (result == null) {206return new byte[0];207}208return result.length == total ?209result : Arrays.copyOf(result, total);210}211212result = new byte[total];213int offset = 0;214remaining = total;215for (byte[] b : bufs) {216int count = Math.min(b.length, remaining);217System.arraycopy(b, 0, result, offset, count);218offset += count;219remaining -= count;220}221222return result;223}224225/**226* Reads the requested number of bytes from the input stream into the given227* byte array. This method blocks until {@code len} bytes of input data have228* been read, end of stream is detected, or an exception is thrown. The229* number of bytes actually read, possibly zero, is returned. This method230* does not close the input stream.231*232* <p> In the case where end of stream is reached before {@code len} bytes233* have been read, then the actual number of bytes read will be returned.234* When this stream reaches end of stream, further invocations of this235* method will return zero.236*237* <p> If {@code len} is zero, then no bytes are read and {@code 0} is238* returned; otherwise, there is an attempt to read up to {@code len} bytes.239*240* <p> The first byte read is stored into element {@code b[off]}, the next241* one in to {@code b[off+1]}, and so on. The number of bytes read is, at242* most, equal to {@code len}. Let <i>k</i> be the number of bytes actually243* read; these bytes will be stored in elements {@code b[off]} through244* {@code b[off+}<i>k</i>{@code -1]}, leaving elements {@code b[off+}<i>k</i>245* {@code ]} through {@code b[off+len-1]} unaffected.246*247* <p> The behavior for the case where the input stream is <i>asynchronously248* closed</i>, or the thread interrupted during the read, is highly input249* stream specific, and therefore not specified.250*251* <p> If an I/O error occurs reading from the input stream, then it may do252* so after some, but not all, bytes of {@code b} have been updated with253* data from the input stream. Consequently the input stream and {@code b}254* may be in an inconsistent state. It is strongly recommended that the255* stream be promptly closed if an I/O error occurs.256*257* @param is input stream, must not be null258* @param b the byte array into which the data is read259* @param off the start offset in {@code b} at which the data is written260* @param len the maximum number of bytes to read261* @return the actual number of bytes read into the buffer262* @throws IOException if an I/O error occurs263* @throws NullPointerException if {@code b} is {@code null}264* @throws IndexOutOfBoundsException If {@code off} is negative, {@code len}265* is negative, or {@code len} is greater than {@code b.length - off}266*267* @since 1.9268*/269public static int readNBytes(InputStream is, byte[] b, int off, int len) throws IOException {270Objects.requireNonNull(b);271if (off < 0 || len < 0 || len > b.length - off)272throw new IndexOutOfBoundsException();273int n = 0;274while (n < len) {275int count = is.read(b, off + n, len - n);276if (count < 0)277break;278n += count;279}280return n;281}282283/**284* Compatibility wrapper for third party users of285* {@code sun.misc.IOUtils.readFully} following its286* removal in JDK-8231139.287*288* Read up to {@code length} of bytes from {@code in}289* until EOF is detected.290*291* @param is input stream, must not be null292* @param length number of bytes to read293* @param readAll if true, an EOFException will be thrown if not enough294* bytes are read.295* @return bytes read296* @throws EOFException if there are not enough bytes in the stream297* @throws IOException if an I/O error occurs or {@code length} is negative298* @throws OutOfMemoryError if an array of the required size cannot be299* allocated.300*/301public static byte[] readFully(InputStream is, int length, boolean readAll)302throws IOException {303if (length < 0) {304throw new IOException("length cannot be negative: " + length);305}306if (readAll) {307return readExactlyNBytes(is, length);308} else {309return readNBytes(is, length);310}311}312}313314315