GNU Classpath (0.95) | |
Frames | No Frames |
1: /* BufferedWriter.java -- Buffer output into large blocks before writing 2: Copyright (C) 1998, 1999, 2000, 2001 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: /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 42: * "The Java Language Specification", ISBN 0-201-63451-1 43: * Status: Complete to version 1.1. 44: */ 45: 46: /** 47: * This class accumulates chars written in a buffer instead of immediately 48: * writing the data to the underlying output sink. The chars are instead 49: * as one large block when the buffer is filled, or when the stream is 50: * closed or explicitly flushed. This mode operation can provide a more 51: * efficient mechanism for writing versus doing numerous small unbuffered 52: * writes. 53: * 54: * @author Aaron M. Renn (arenn@urbanophile.com) 55: * @author Tom Tromey (tromey@cygnus.com) 56: * @date September 25, 1998 57: */ 58: public class BufferedWriter extends Writer 59: { 60: /** 61: * This is the default buffer size 62: */ 63: private static final int DEFAULT_BUFFER_SIZE = 8192; 64: 65: /** 66: * This is the underlying <code>Writer</code> to which this object 67: * sends its output. 68: */ 69: private Writer out; 70: 71: /** 72: * This is the internal char array used for buffering output before 73: * writing it. 74: */ 75: char[] buffer; 76: 77: /** 78: * This is the number of chars that are currently in the buffer and 79: * are waiting to be written to the underlying stream. It always points to 80: * the index into the buffer where the next char of data will be stored 81: */ 82: int count; 83: 84: /** 85: * This method initializes a new <code>BufferedWriter</code> instance 86: * that will write to the specified subordinate <code>Writer</code> 87: * and which will use a default buffer size of 8192 chars. 88: * 89: * @param out The underlying <code>Writer</code> to write data to 90: */ 91: public BufferedWriter (Writer out) 92: { 93: this (out, DEFAULT_BUFFER_SIZE); 94: } 95: 96: /** 97: * This method initializes a new <code>BufferedWriter</code> instance 98: * that will write to the specified subordinate <code>Writer</code> 99: * and which will use the specified buffer size 100: * 101: * @param out The underlying <code>Writer</code> to write data to 102: * @param size The size of the internal buffer 103: */ 104: public BufferedWriter (Writer out, int size) 105: { 106: super(out.lock); 107: this.out = out; 108: this.buffer = new char[size]; 109: this.count = 0; 110: } 111: 112: /** 113: * This method flushes any remaining buffered chars then closes the 114: * underlying output stream. Any further attempts to write to this stream 115: * may throw an exception 116: * 117: * @exception IOException If an error occurs. 118: */ 119: public void close () throws IOException 120: { 121: synchronized (lock) 122: { 123: // It is safe to call localFlush even if the stream is already 124: // closed. 125: localFlush (); 126: out.close(); 127: buffer = null; 128: } 129: } 130: 131: /** 132: * This method causes any currently buffered chars to be immediately 133: * written to the underlying output stream. 134: * 135: * @exception IOException If an error occurs 136: */ 137: public void flush () throws IOException 138: { 139: synchronized (lock) 140: { 141: if (buffer == null) 142: throw new IOException ("Stream closed"); 143: localFlush (); 144: out.flush(); 145: } 146: } 147: 148: /** 149: * This method writes out a system depedent line separator sequence. The 150: * actual value written is detemined from the <xmp>line.separator</xmp> 151: * system property. 152: * 153: * @exception IOException If an error occurs 154: */ 155: public void newLine () throws IOException 156: { 157: write (System.getProperty("line.separator")); 158: } 159: 160: /** 161: * This method writes a single char of data. This will be written to the 162: * buffer instead of the underlying data source. However, if the buffer 163: * is filled as a result of this write request, it will be flushed to the 164: * underlying output stream. 165: * 166: * @param oneChar The char of data to be written, passed as an int 167: * 168: * @exception IOException If an error occurs 169: */ 170: public void write (int oneChar) throws IOException 171: { 172: synchronized (lock) 173: { 174: if (buffer == null) 175: throw new IOException ("Stream closed"); 176: buffer[count++] = (char) oneChar; 177: if (count == buffer.length) 178: localFlush (); 179: } 180: } 181: 182: /** 183: * This method writes <code>len</code> chars from the char array 184: * <code>buf</code> starting at position <code>offset</code> in the buffer. 185: * These chars will be written to the internal buffer. However, if this 186: * write operation fills the buffer, the buffer will be flushed to the 187: * underlying output stream. 188: * 189: * @param buf The array of chars to write. 190: * @param offset The index into the char array to start writing from. 191: * @param len The number of chars to write. 192: * 193: * @exception IOException If an error occurs 194: */ 195: public void write (char[] buf, int offset, int len) throws IOException 196: { 197: synchronized (lock) 198: { 199: if (buffer == null) 200: throw new IOException ("Stream closed"); 201: 202: // Bypass buffering if there is too much incoming data. 203: if (count + len > buffer.length) 204: { 205: localFlush (); 206: out.write(buf, offset, len); 207: } 208: else 209: { 210: System.arraycopy(buf, offset, buffer, count, len); 211: count += len; 212: if (count == buffer.length) 213: localFlush (); 214: } 215: } 216: } 217: 218: /** 219: * This method writes <code>len</code> chars from the <code>String</code> 220: * <code>str</code> starting at position <code>offset</code> in the string. 221: * These chars will be written to the internal buffer. However, if this 222: * write operation fills the buffer, the buffer will be flushed to the 223: * underlying output stream. 224: * 225: * @param str The <code>String</code> to write. 226: * @param offset The index into the string to start writing from. 227: * @param len The number of chars to write. 228: * 229: * @exception IOException If an error occurs 230: */ 231: public void write (String str, int offset, int len) throws IOException 232: { 233: synchronized (lock) 234: { 235: if (buffer == null) 236: throw new IOException ("Stream closed"); 237: 238: if (count + len > buffer.length) 239: { 240: localFlush (); 241: out.write(str, offset, len); 242: } 243: else 244: { 245: str.getChars(offset, offset + len, buffer, count); 246: count += len; 247: if (count == buffer.length) 248: localFlush (); 249: } 250: } 251: } 252: 253: // This should only be called with the lock held. 254: private void localFlush () throws IOException 255: { 256: if (count > 0) 257: { 258: out.write(buffer, 0, count); 259: count = 0; 260: } 261: } 262: }
GNU Classpath (0.95) |