1 /* 2 * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.io; 27 28 /** 29 * The class implements a buffered output stream. By setting up such 30 * an output stream, an application can write bytes to the underlying 31 * output stream without necessarily causing a call to the underlying 32 * system for each byte written. 33 * 34 * @author Arthur van Hoff 35 * @since 1.0 36 */ 37 public class BufferedOutputStream extends FilterOutputStream { 38 /** 39 * The internal buffer where data is stored. 40 */ 41 protected byte buf[]; 42 43 /** 44 * The number of valid bytes in the buffer. This value is always 45 * in the range {@code 0} through {@code buf.length}; elements 46 * {@code buf[0]} through {@code buf[count-1]} contain valid 47 * byte data. 48 */ 49 protected int count; 50 51 /** 52 * Creates a new buffered output stream to write data to the 53 * specified underlying output stream. 54 * 55 * @param out the underlying output stream. 56 */ BufferedOutputStream(OutputStream out)57 public BufferedOutputStream(OutputStream out) { 58 this(out, 8192); 59 } 60 61 /** 62 * Creates a new buffered output stream to write data to the 63 * specified underlying output stream with the specified buffer 64 * size. 65 * 66 * @param out the underlying output stream. 67 * @param size the buffer size. 68 * @throws IllegalArgumentException if size <= 0. 69 */ BufferedOutputStream(OutputStream out, int size)70 public BufferedOutputStream(OutputStream out, int size) { 71 super(out); 72 if (size <= 0) { 73 throw new IllegalArgumentException("Buffer size <= 0"); 74 } 75 buf = new byte[size]; 76 } 77 78 /** Flush the internal buffer */ flushBuffer()79 private void flushBuffer() throws IOException { 80 if (count > 0) { 81 out.write(buf, 0, count); 82 count = 0; 83 } 84 } 85 86 /** 87 * Writes the specified byte to this buffered output stream. 88 * 89 * @param b the byte to be written. 90 * @throws IOException if an I/O error occurs. 91 */ 92 @Override write(int b)93 public synchronized void write(int b) throws IOException { 94 if (count >= buf.length) { 95 flushBuffer(); 96 } 97 buf[count++] = (byte)b; 98 } 99 100 /** 101 * Writes {@code len} bytes from the specified byte array 102 * starting at offset {@code off} to this buffered output stream. 103 * 104 * <p> Ordinarily this method stores bytes from the given array into this 105 * stream's buffer, flushing the buffer to the underlying output stream as 106 * needed. If the requested length is at least as large as this stream's 107 * buffer, however, then this method will flush the buffer and write the 108 * bytes directly to the underlying output stream. Thus redundant 109 * {@code BufferedOutputStream}s will not copy data unnecessarily. 110 * 111 * @param b the data. 112 * @param off the start offset in the data. 113 * @param len the number of bytes to write. 114 * @throws IOException if an I/O error occurs. 115 */ 116 @Override write(byte b[], int off, int len)117 public synchronized void write(byte b[], int off, int len) throws IOException { 118 if (len >= buf.length) { 119 /* If the request length exceeds the size of the output buffer, 120 flush the output buffer and then write the data directly. 121 In this way buffered streams will cascade harmlessly. */ 122 flushBuffer(); 123 out.write(b, off, len); 124 return; 125 } 126 if (len > buf.length - count) { 127 flushBuffer(); 128 } 129 System.arraycopy(b, off, buf, count, len); 130 count += len; 131 } 132 133 /** 134 * Flushes this buffered output stream. This forces any buffered 135 * output bytes to be written out to the underlying output stream. 136 * 137 * @throws IOException if an I/O error occurs. 138 * @see java.io.FilterOutputStream#out 139 */ 140 @Override flush()141 public synchronized void flush() throws IOException { 142 flushBuffer(); 143 out.flush(); 144 } 145 } 146