Path: blob/master/src/java.base/share/classes/java/io/ByteArrayOutputStream.java
41152 views
/*1* Copyright (c) 1994, 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*/2425package java.io;2627import java.nio.charset.Charset;28import java.util.Arrays;29import java.util.Objects;3031import jdk.internal.util.ArraysSupport;3233/**34* This class implements an output stream in which the data is35* written into a byte array. The buffer automatically grows as data36* is written to it.37* The data can be retrieved using {@code toByteArray()} and38* {@code toString()}.39* <p>40* Closing a {@code ByteArrayOutputStream} has no effect. The methods in41* this class can be called after the stream has been closed without42* generating an {@code IOException}.43*44* @author Arthur van Hoff45* @since 1.046*/4748public class ByteArrayOutputStream extends OutputStream {4950/**51* The buffer where data is stored.52*/53protected byte buf[];5455/**56* The number of valid bytes in the buffer.57*/58protected int count;5960/**61* Creates a new {@code ByteArrayOutputStream}. The buffer capacity is62* initially 32 bytes, though its size increases if necessary.63*/64public ByteArrayOutputStream() {65this(32);66}6768/**69* Creates a new {@code ByteArrayOutputStream}, with a buffer capacity of70* the specified size, in bytes.71*72* @param size the initial size.73* @throws IllegalArgumentException if size is negative.74*/75public ByteArrayOutputStream(int size) {76if (size < 0) {77throw new IllegalArgumentException("Negative initial size: "78+ size);79}80buf = new byte[size];81}8283/**84* Increases the capacity if necessary to ensure that it can hold85* at least the number of elements specified by the minimum86* capacity argument.87*88* @param minCapacity the desired minimum capacity.89* @throws OutOfMemoryError if {@code minCapacity < 0} and90* {@code minCapacity - buf.length > 0}. This is interpreted as a91* request for the unsatisfiably large capacity.92* {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}.93*/94private void ensureCapacity(int minCapacity) {95// overflow-conscious code96int oldCapacity = buf.length;97int minGrowth = minCapacity - oldCapacity;98if (minGrowth > 0) {99buf = Arrays.copyOf(buf, ArraysSupport.newLength(oldCapacity,100minGrowth, oldCapacity /* preferred growth */));101}102}103104/**105* Writes the specified byte to this {@code ByteArrayOutputStream}.106*107* @param b the byte to be written.108*/109public synchronized void write(int b) {110ensureCapacity(count + 1);111buf[count] = (byte) b;112count += 1;113}114115/**116* Writes {@code len} bytes from the specified byte array117* starting at offset {@code off} to this {@code ByteArrayOutputStream}.118*119* @param b the data.120* @param off the start offset in the data.121* @param len the number of bytes to write.122* @throws NullPointerException if {@code b} is {@code null}.123* @throws IndexOutOfBoundsException if {@code off} is negative,124* {@code len} is negative, or {@code len} is greater than125* {@code b.length - off}126*/127public synchronized void write(byte b[], int off, int len) {128Objects.checkFromIndexSize(off, len, b.length);129ensureCapacity(count + len);130System.arraycopy(b, off, buf, count, len);131count += len;132}133134/**135* Writes the complete contents of the specified byte array136* to this {@code ByteArrayOutputStream}.137*138* @apiNote139* This method is equivalent to {@link #write(byte[],int,int)140* write(b, 0, b.length)}.141*142* @param b the data.143* @throws NullPointerException if {@code b} is {@code null}.144* @since 11145*/146public void writeBytes(byte b[]) {147write(b, 0, b.length);148}149150/**151* Writes the complete contents of this {@code ByteArrayOutputStream} to152* the specified output stream argument, as if by calling the output153* stream's write method using {@code out.write(buf, 0, count)}.154*155* @param out the output stream to which to write the data.156* @throws NullPointerException if {@code out} is {@code null}.157* @throws IOException if an I/O error occurs.158*/159public synchronized void writeTo(OutputStream out) throws IOException {160out.write(buf, 0, count);161}162163/**164* Resets the {@code count} field of this {@code ByteArrayOutputStream}165* to zero, so that all currently accumulated output in the166* output stream is discarded. The output stream can be used again,167* reusing the already allocated buffer space.168*169* @see java.io.ByteArrayInputStream#count170*/171public synchronized void reset() {172count = 0;173}174175/**176* Creates a newly allocated byte array. Its size is the current177* size of this output stream and the valid contents of the buffer178* have been copied into it.179*180* @return the current contents of this output stream, as a byte array.181* @see java.io.ByteArrayOutputStream#size()182*/183public synchronized byte[] toByteArray() {184return Arrays.copyOf(buf, count);185}186187/**188* Returns the current size of the buffer.189*190* @return the value of the {@code count} field, which is the number191* of valid bytes in this output stream.192* @see java.io.ByteArrayOutputStream#count193*/194public synchronized int size() {195return count;196}197198/**199* Converts the buffer's contents into a string decoding bytes using the200* platform's default character set. The length of the new {@code String}201* is a function of the character set, and hence may not be equal to the202* size of the buffer.203*204* <p> This method always replaces malformed-input and unmappable-character205* sequences with the default replacement string for the platform's206* default character set. The {@linkplain java.nio.charset.CharsetDecoder}207* class should be used when more control over the decoding process is208* required.209*210* @return String decoded from the buffer's contents.211* @since 1.1212*/213public synchronized String toString() {214return new String(buf, 0, count);215}216217/**218* Converts the buffer's contents into a string by decoding the bytes using219* the named {@link java.nio.charset.Charset charset}.220*221* <p> This method is equivalent to {@code #toString(charset)} that takes a222* {@link java.nio.charset.Charset charset}.223*224* <p> An invocation of this method of the form225*226* <pre> {@code227* ByteArrayOutputStream b = ...228* b.toString("UTF-8")229* }230* </pre>231*232* behaves in exactly the same way as the expression233*234* <pre> {@code235* ByteArrayOutputStream b = ...236* b.toString(StandardCharsets.UTF_8)237* }238* </pre>239*240*241* @param charsetName the name of a supported242* {@link java.nio.charset.Charset charset}243* @return String decoded from the buffer's contents.244* @throws UnsupportedEncodingException245* If the named charset is not supported246* @since 1.1247*/248public synchronized String toString(String charsetName)249throws UnsupportedEncodingException250{251return new String(buf, 0, count, charsetName);252}253254/**255* Converts the buffer's contents into a string by decoding the bytes using256* the specified {@link java.nio.charset.Charset charset}. The length of the new257* {@code String} is a function of the charset, and hence may not be equal258* to the length of the byte array.259*260* <p> This method always replaces malformed-input and unmappable-character261* sequences with the charset's default replacement string. The {@link262* java.nio.charset.CharsetDecoder} class should be used when more control263* over the decoding process is required.264*265* @param charset the {@linkplain java.nio.charset.Charset charset}266* to be used to decode the {@code bytes}267* @return String decoded from the buffer's contents.268* @since 10269*/270public synchronized String toString(Charset charset) {271return new String(buf, 0, count, charset);272}273274/**275* Creates a newly allocated string. Its size is the current size of276* the output stream and the valid contents of the buffer have been277* copied into it. Each character <i>c</i> in the resulting string is278* constructed from the corresponding element <i>b</i> in the byte279* array such that:280* <blockquote><pre>{@code281* c == (char)(((hibyte & 0xff) << 8) | (b & 0xff))282* }</pre></blockquote>283*284* @deprecated This method does not properly convert bytes into characters.285* As of JDK 1.1, the preferred way to do this is via the286* {@link #toString(String charsetName)} or {@link #toString(Charset charset)}287* method, which takes an encoding-name or charset argument,288* or the {@code toString()} method, which uses the platform's default289* character encoding.290*291* @param hibyte the high byte of each resulting Unicode character.292* @return the current contents of the output stream, as a string.293* @see java.io.ByteArrayOutputStream#size()294* @see java.io.ByteArrayOutputStream#toString(String)295* @see java.io.ByteArrayOutputStream#toString()296*/297@Deprecated298public synchronized String toString(int hibyte) {299return new String(buf, hibyte, 0, count);300}301302/**303* Closing a {@code ByteArrayOutputStream} has no effect. The methods in304* this class can be called after the stream has been closed without305* generating an {@code IOException}.306*/307public void close() throws IOException {308}309310}311312313