Frames | No Frames |
1: /* BufferedOutputStream.java -- Buffer output into large blocks before writing 2: Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.io; 40: 41: /** 42: * This class accumulates bytes written in a buffer instead of immediately 43: * writing the data to the underlying output sink. The bytes are instead 44: * as one large block when the buffer is filled, or when the stream is 45: * closed or explicitly flushed. This mode operation can provide a more 46: * efficient mechanism for writing versus doing numerous small unbuffered 47: * writes. 48: * 49: * @author Aaron M. Renn (arenn@urbanophile.com) 50: */ 51: public class BufferedOutputStream extends FilterOutputStream 52: { 53: /** 54: * This is the default buffer size 55: */ 56: private static final int DEFAULT_BUFFER_SIZE = 512; 57: 58: /** 59: * This is the internal byte array used for buffering output before 60: * writing it. 61: */ 62: protected byte[] buf; 63: 64: /** 65: * This is the number of bytes that are currently in the buffer and 66: * are waiting to be written to the underlying stream. It always points to 67: * the index into the buffer where the next byte of data will be stored 68: */ 69: protected int count; 70: 71: /** 72: * This method initializes a new <code>BufferedOutputStream</code> instance 73: * that will write to the specified subordinate <code>OutputStream</code> 74: * and which will use a default buffer size of 512 bytes. 75: * 76: * @param out The underlying <code>OutputStream</code> to write data to 77: */ 78: public BufferedOutputStream(OutputStream out) 79: { 80: this(out, DEFAULT_BUFFER_SIZE); 81: } 82: 83: /** 84: * This method initializes a new <code>BufferedOutputStream</code> instance 85: * that will write to the specified subordinate <code>OutputStream</code> 86: * and which will use the specified buffer size 87: * 88: * @param out The underlying <code>OutputStream</code> to write data to 89: * @param size The size of the internal buffer 90: */ 91: public BufferedOutputStream(OutputStream out, int size) 92: { 93: super(out); 94: 95: buf = new byte[size]; 96: } 97: 98: /** 99: * This method causes any currently buffered bytes to be immediately 100: * written to the underlying output stream. 101: * 102: * @exception IOException If an error occurs 103: */ 104: public synchronized void flush() throws IOException 105: { 106: if (count == 0) 107: return; 108: 109: out.write(buf, 0, count); 110: count = 0; 111: out.flush(); 112: } 113: 114: /** 115: * This method flushes any remaining buffered bytes then closes the 116: * underlying output stream. Any further attempts to write to this stream 117: * may throw an exception 118: * 119: public synchronized void close() throws IOException 120: { 121: flush(); 122: out.close(); 123: } 124: */ 125: 126: /** 127: * This method runs when the object is garbage collected. It is 128: * responsible for ensuring that all buffered bytes are written and 129: * for closing the underlying stream. 130: * 131: * @exception IOException If an error occurs (ignored by the Java runtime) 132: * 133: protected void finalize() throws IOException 134: { 135: close(); 136: } 137: */ 138: 139: /** 140: * This method writes a single byte of data. This will be written to the 141: * buffer instead of the underlying data source. However, if the buffer 142: * is filled as a result of this write request, it will be flushed to the 143: * underlying output stream. 144: * 145: * @param b The byte of data to be written, passed as an int 146: * 147: * @exception IOException If an error occurs 148: */ 149: public synchronized void write(int b) throws IOException 150: { 151: if (count == buf.length) 152: flush(); 153: 154: buf[count] = (byte)(b & 0xFF); 155: ++count; 156: } 157: 158: /** 159: * This method writes <code>len</code> bytes from the byte array 160: * <code>buf</code> starting at position <code>offset</code> in the buffer. 161: * These bytes will be written to the internal buffer. However, if this 162: * write operation fills the buffer, the buffer will be flushed to the 163: * underlying output stream. 164: * 165: * @param buf The array of bytes to write. 166: * @param offset The index into the byte array to start writing from. 167: * @param len The number of bytes to write. 168: * 169: * @exception IOException If an error occurs 170: */ 171: public synchronized void write(byte[] buf, int offset, int len) 172: throws IOException 173: { 174: // Buffer can hold everything. Note that the case where LEN < 0 175: // is automatically handled by the downstream write. 176: if (len < (this.buf.length - count)) 177: { 178: System.arraycopy(buf, offset, this.buf, count, len); 179: count += len; 180: } 181: else 182: { 183: // The write was too big. So flush the buffer and write the new 184: // bytes directly to the underlying stream, per the JDK 1.2 185: // docs. 186: flush(); 187: out.write (buf, offset, len); 188: } 189: } 190: 191: } // class BufferedOutputStream