|
1 | 1 | /* |
2 | | - * Licensed to the Apache Software Foundation (ASF) under one or more |
3 | | - * contributor license agreements. See the NOTICE file distributed with |
4 | | - * this work for additional information regarding copyright ownership. |
5 | | - * The ASF licenses this file to You under the Apache License, Version 2.0 |
6 | | - * (the "License"); you may not use this file except in compliance with |
7 | | - * the License. You may obtain a copy of the License at |
| 2 | + * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved. |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
8 | 4 | * |
9 | | - * http://www.apache.org/licenses/LICENSE-2.0 |
| 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 | 10 | * |
11 | | - * Unless required by applicable law or agreed to in writing, software |
12 | | - * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | - * See the License for the specific language governing permissions and |
15 | | - * limitations under the License. |
| 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. |
16 | 24 | */ |
17 | 25 |
|
18 | 26 | package java.io; |
19 | 27 |
|
20 | | -import org.apache.harmony.luni.util.Msg; |
21 | | - |
22 | 28 | /** |
23 | | - * BufferedOutputStream is a class which takes an output stream and |
24 | | - * <em>buffers</em> the writes to that stream. In this way, costly interaction |
25 | | - * with the original output stream can be minimized by writing buffered amounts |
26 | | - * of data infrequently. The drawback is that extra space is required to hold |
27 | | - * the buffer and copying takes place when writing that buffer. |
28 | | - * |
29 | | - * @see BufferedInputStream |
| 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 JDK1.0 |
30 | 36 | */ |
31 | | -public class BufferedOutputStream extends FilterOutputStream { |
| 37 | +public |
| 38 | +class BufferedOutputStream extends FilterOutputStream { |
32 | 39 | /** |
33 | | - * The buffer containing the bytes to be written to the target OutputStream. |
| 40 | + * The internal buffer where data is stored. |
34 | 41 | */ |
35 | | - protected byte[] buf; |
| 42 | + protected byte buf[]; |
36 | 43 |
|
37 | 44 | /** |
38 | | - * The total number of bytes inside the byte array <code>buf</code>. |
| 45 | + * The number of valid bytes in the buffer. This value is always |
| 46 | + * in the range <tt>0</tt> through <tt>buf.length</tt>; elements |
| 47 | + * <tt>buf[0]</tt> through <tt>buf[count-1]</tt> contain valid |
| 48 | + * byte data. |
39 | 49 | */ |
40 | 50 | protected int count; |
41 | 51 |
|
42 | 52 | /** |
43 | | - * Constructs a new BufferedOutputStream on the OutputStream |
44 | | - * <code>out</code>. The default buffer size (8Kb) is allocated and all |
45 | | - * writes are now filtered through this stream. |
46 | | - * |
47 | | - * @param out |
48 | | - * the OutputStream to buffer writes on. |
| 53 | + * Creates a new buffered output stream to write data to the |
| 54 | + * specified underlying output stream. |
| 55 | + * |
| 56 | + * @param out the underlying output stream. |
49 | 57 | */ |
50 | 58 | public BufferedOutputStream(OutputStream out) { |
51 | | - super(out); |
52 | | - buf = new byte[8192]; |
| 59 | + this(out, 8192); |
53 | 60 | } |
54 | 61 |
|
55 | 62 | /** |
56 | | - * Constructs a new BufferedOutputStream on the OutputStream |
57 | | - * <code>out</code>. The buffer size is set to <code>size</code> and |
58 | | - * all writes are now filtered through this stream. |
59 | | - * |
60 | | - * @param out |
61 | | - * the OutputStream to buffer writes on. |
62 | | - * @param size |
63 | | - * the size of the buffer in bytes. |
64 | | - * @throws IllegalArgumentException |
65 | | - * the size is <= 0 |
| 63 | + * Creates a new buffered output stream to write data to the |
| 64 | + * specified underlying output stream with the specified buffer |
| 65 | + * size. |
| 66 | + * |
| 67 | + * @param out the underlying output stream. |
| 68 | + * @param size the buffer size. |
| 69 | + * @exception IllegalArgumentException if size <= 0. |
66 | 70 | */ |
67 | 71 | public BufferedOutputStream(OutputStream out, int size) { |
68 | 72 | super(out); |
69 | 73 | if (size <= 0) { |
70 | | - // K0058=size must be > 0 |
71 | | - throw new IllegalArgumentException(Msg.getString("K0058")); //$NON-NLS-1$ |
| 74 | + throw new IllegalArgumentException("Buffer size <= 0"); |
72 | 75 | } |
73 | 76 | buf = new byte[size]; |
74 | 77 | } |
75 | 78 |
|
76 | | - /** |
77 | | - * Flush this BufferedOutputStream to ensure all pending data is written out |
78 | | - * to the target OutputStream. In addition, the target stream is also |
79 | | - * flushed. |
80 | | - * |
81 | | - * @throws IOException |
82 | | - * If an error occurs attempting to flush this |
83 | | - * BufferedOutputStream. |
84 | | - */ |
85 | | - @Override |
86 | | - public synchronized void flush() throws IOException { |
| 79 | + /** Flush the internal buffer */ |
| 80 | + private void flushBuffer() throws IOException { |
87 | 81 | if (count > 0) { |
88 | 82 | out.write(buf, 0, count); |
| 83 | + count = 0; |
89 | 84 | } |
90 | | - count = 0; |
91 | | - out.flush(); |
92 | 85 | } |
93 | 86 |
|
94 | 87 | /** |
95 | | - * Writes <code>count</code> <code>bytes</code> from the byte array |
96 | | - * <code>buffer</code> starting at <code>offset</code> to this |
97 | | - * BufferedOutputStream. If there is room in the buffer to hold the bytes, |
98 | | - * they are copied in. If not, the buffered bytes plus the bytes in |
99 | | - * <code>buffer</code> are written to the target stream, the target is |
100 | | - * flushed, and the buffer is cleared. |
101 | | - * |
102 | | - * @param buffer |
103 | | - * the buffer to be written |
104 | | - * @param offset |
105 | | - * offset in buffer to get bytes |
106 | | - * @param length |
107 | | - * number of bytes in buffer to write |
108 | | - * |
109 | | - * @throws IOException |
110 | | - * If an error occurs attempting to write to this |
111 | | - * BufferedOutputStream. |
112 | | - * @throws NullPointerException |
113 | | - * If buffer is null. |
114 | | - * @throws ArrayIndexOutOfBoundsException |
115 | | - * If offset or count is outside of bounds. |
| 88 | + * Writes the specified byte to this buffered output stream. |
| 89 | + * |
| 90 | + * @param b the byte to be written. |
| 91 | + * @exception IOException if an I/O error occurs. |
116 | 92 | */ |
117 | | - @Override |
118 | | - public synchronized void write(byte[] buffer, int offset, int length) |
119 | | - throws IOException { |
120 | | - if (buffer == null) { |
121 | | - // K0047=buffer is null |
122 | | - throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$ |
123 | | - } |
124 | | - if (offset < 0 || offset > buffer.length - length || length < 0) { |
125 | | - // K002f=Arguments out of bounds |
126 | | - throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$ |
| 93 | + public synchronized void write(int b) throws IOException { |
| 94 | + if (count >= buf.length) { |
| 95 | + flushBuffer(); |
127 | 96 | } |
128 | | - if (count == 0 && length >= buf.length) { |
129 | | - out.write(buffer, offset, length); |
| 97 | + buf[count++] = (byte)b; |
| 98 | + } |
| 99 | + |
| 100 | + /** |
| 101 | + * Writes <code>len</code> bytes from the specified byte array |
| 102 | + * starting at offset <code>off</code> 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</code>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 | + * @exception IOException if an I/O error occurs. |
| 115 | + */ |
| 116 | + public synchronized void write(byte b[], int off, int len) throws IOException { |
| 117 | + if (len >= buf.length) { |
| 118 | + /* If the request length exceeds the size of the output buffer, |
| 119 | + flush the output buffer and then write the data directly. |
| 120 | + In this way buffered streams will cascade harmlessly. */ |
| 121 | + flushBuffer(); |
| 122 | + out.write(b, off, len); |
130 | 123 | return; |
131 | 124 | } |
132 | | - int available = buf.length - count; |
133 | | - if (length < available) { |
134 | | - available = length; |
135 | | - } |
136 | | - if (available > 0) { |
137 | | - System.arraycopy(buffer, offset, buf, count, available); |
138 | | - count += available; |
139 | | - } |
140 | | - if (count == buf.length) { |
141 | | - out.write(buf, 0, buf.length); |
142 | | - count = 0; |
143 | | - if (length > available) { |
144 | | - offset += available; |
145 | | - available = length - available; |
146 | | - if (available >= buf.length) { |
147 | | - out.write(buffer, offset, available); |
148 | | - } else { |
149 | | - System.arraycopy(buffer, offset, buf, count, available); |
150 | | - count += available; |
151 | | - } |
152 | | - } |
| 125 | + if (len > buf.length - count) { |
| 126 | + flushBuffer(); |
153 | 127 | } |
| 128 | + System.arraycopy(b, off, buf, count, len); |
| 129 | + count += len; |
154 | 130 | } |
155 | 131 |
|
156 | 132 | /** |
157 | | - * Writes the specified byte <code>oneByte</code> to this |
158 | | - * BufferedOutputStream. Only the low order byte of <code>oneByte</code> |
159 | | - * is written. If there is room in the buffer, the byte is copied in and the |
160 | | - * count incremented. Otherwise, the buffer plus <code>oneByte</code> are |
161 | | - * written to the target stream, the target is flushed, and the buffer is |
162 | | - * reset. |
163 | | - * |
164 | | - * @param oneByte |
165 | | - * the byte to be written |
166 | | - * |
167 | | - * @throws IOException |
168 | | - * If an error occurs attempting to write to this |
169 | | - * BufferedOutputStream. |
| 133 | + * Flushes this buffered output stream. This forces any buffered |
| 134 | + * output bytes to be written out to the underlying output stream. |
| 135 | + * |
| 136 | + * @exception IOException if an I/O error occurs. |
| 137 | + * @see java.io.FilterOutputStream#out |
170 | 138 | */ |
171 | | - @Override |
172 | | - public synchronized void write(int oneByte) throws IOException { |
173 | | - if (count == buf.length) { |
174 | | - out.write(buf, 0, count); |
175 | | - count = 0; |
176 | | - } |
177 | | - buf[count++] = (byte) oneByte; |
178 | | - } |
179 | | - |
180 | | - @Override |
181 | | - public int hashCode() { |
182 | | - try { |
183 | | - flush(); |
184 | | - } catch (IOException e) { |
185 | | - } |
186 | | - return out.hashCode(); |
| 139 | + public synchronized void flush() throws IOException { |
| 140 | + flushBuffer(); |
| 141 | + out.flush(); |
187 | 142 | } |
188 | 143 | } |
0 commit comments