1/* 2 * Copyright (c) 1996, 2011, 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 26package java.io; 27 28 29/** 30 * Abstract class for writing to character streams. The only methods that a 31 * subclass must implement are write(char[], int, int), flush(), and close(). 32 * Most subclasses, however, will override some of the methods defined here in 33 * order to provide higher efficiency, additional functionality, or both. 34 * 35 * @see Writer 36 * @see BufferedWriter 37 * @see CharArrayWriter 38 * @see FilterWriter 39 * @see OutputStreamWriter 40 * @see FileWriter 41 * @see PipedWriter 42 * @see PrintWriter 43 * @see StringWriter 44 * @see Reader 45 * 46 * @author Mark Reinhold 47 * @since JDK1.1 48 */ 49 50public abstract class Writer implements Appendable, Closeable, Flushable { 51 52 /** 53 * Temporary buffer used to hold writes of strings and single characters 54 */ 55 private char[] writeBuffer; 56 57 /** 58 * Size of writeBuffer, must be >= 1 59 */ 60 private static final int WRITE_BUFFER_SIZE = 1024; 61 62 /** 63 * The object used to synchronize operations on this stream. For 64 * efficiency, a character-stream object may use an object other than 65 * itself to protect critical sections. A subclass should therefore use 66 * the object in this field rather than <tt>this</tt> or a synchronized 67 * method. 68 */ 69 protected Object lock; 70 71 /** 72 * Creates a new character-stream writer whose critical sections will 73 * synchronize on the writer itself. 74 */ 75 protected Writer() { 76 this.lock = this; 77 } 78 79 /** 80 * Creates a new character-stream writer whose critical sections will 81 * synchronize on the given object. 82 * 83 * @param lock 84 * Object to synchronize on 85 */ 86 protected Writer(Object lock) { 87 if (lock == null) { 88 throw new NullPointerException(); 89 } 90 this.lock = lock; 91 } 92 93 /** 94 * Writes a single character. The character to be written is contained in 95 * the 16 low-order bits of the given integer value; the 16 high-order bits 96 * are ignored. 97 * 98 * <p> Subclasses that intend to support efficient single-character output 99 * should override this method. 100 * 101 * @param c 102 * int specifying a character to be written 103 * 104 * @throws IOException 105 * If an I/O error occurs 106 */ 107 public void write(int c) throws IOException { 108 synchronized (lock) { 109 if (writeBuffer == null){ 110 writeBuffer = new char[WRITE_BUFFER_SIZE]; 111 } 112 writeBuffer[0] = (char) c; 113 write(writeBuffer, 0, 1); 114 } 115 } 116 117 /** 118 * Writes an array of characters. 119 * 120 * @param cbuf 121 * Array of characters to be written 122 * 123 * @throws IOException 124 * If an I/O error occurs 125 */ 126 public void write(char cbuf[]) throws IOException { 127 write(cbuf, 0, cbuf.length); 128 } 129 130 /** 131 * Writes a portion of an array of characters. 132 * 133 * @param cbuf 134 * Array of characters 135 * 136 * @param off 137 * Offset from which to start writing characters 138 * 139 * @param len 140 * Number of characters to write 141 * 142 * @throws IOException 143 * If an I/O error occurs 144 */ 145 abstract public void write(char cbuf[], int off, int len) throws IOException; 146 147 /** 148 * Writes a string. 149 * 150 * @param str 151 * String to be written 152 * 153 * @throws IOException 154 * If an I/O error occurs 155 */ 156 public void write(String str) throws IOException { 157 write(str, 0, str.length()); 158 } 159 160 /** 161 * Writes a portion of a string. 162 * 163 * @param str 164 * A String 165 * 166 * @param off 167 * Offset from which to start writing characters 168 * 169 * @param len 170 * Number of characters to write 171 * 172 * @throws IndexOutOfBoundsException 173 * If <tt>off</tt> is negative, or <tt>len</tt> is negative, 174 * or <tt>off+len</tt> is negative or greater than the length 175 * of the given string 176 * 177 * @throws IOException 178 * If an I/O error occurs 179 */ 180 public void write(String str, int off, int len) throws IOException { 181 synchronized (lock) { 182 char cbuf[]; 183 if (len <= WRITE_BUFFER_SIZE) { 184 if (writeBuffer == null) { 185 writeBuffer = new char[WRITE_BUFFER_SIZE]; 186 } 187 cbuf = writeBuffer; 188 } else { // Don't permanently allocate very large buffers. 189 cbuf = new char[len]; 190 } 191 str.getChars(off, (off + len), cbuf, 0); 192 write(cbuf, 0, len); 193 } 194 } 195 196 /** 197 * Appends the specified character sequence to this writer. 198 * 199 * <p> An invocation of this method of the form <tt>out.append(csq)</tt> 200 * behaves in exactly the same way as the invocation 201 * 202 * <pre> 203 * out.write(csq.toString()) </pre> 204 * 205 * <p> Depending on the specification of <tt>toString</tt> for the 206 * character sequence <tt>csq</tt>, the entire sequence may not be 207 * appended. For instance, invoking the <tt>toString</tt> method of a 208 * character buffer will return a subsequence whose content depends upon 209 * the buffer's position and limit. 210 * 211 * @param csq 212 * The character sequence to append. If <tt>csq</tt> is 213 * <tt>null</tt>, then the four characters <tt>"null"</tt> are 214 * appended to this writer. 215 * 216 * @return This writer 217 * 218 * @throws IOException 219 * If an I/O error occurs 220 * 221 * @since 1.5 222 */ 223 public Writer append(CharSequence csq) throws IOException { 224 if (csq == null) 225 write("null"); 226 else 227 write(csq.toString()); 228 return this; 229 } 230 231 /** 232 * Appends a subsequence of the specified character sequence to this writer. 233 * <tt>Appendable</tt>. 234 * 235 * <p> An invocation of this method of the form <tt>out.append(csq, start, 236 * end)</tt> when <tt>csq</tt> is not <tt>null</tt> behaves in exactly the 237 * same way as the invocation 238 * 239 * <pre> 240 * out.write(csq.subSequence(start, end).toString()) </pre> 241 * 242 * @param csq 243 * The character sequence from which a subsequence will be 244 * appended. If <tt>csq</tt> is <tt>null</tt>, then characters 245 * will be appended as if <tt>csq</tt> contained the four 246 * characters <tt>"null"</tt>. 247 * 248 * @param start 249 * The index of the first character in the subsequence 250 * 251 * @param end 252 * The index of the character following the last character in the 253 * subsequence 254 * 255 * @return This writer 256 * 257 * @throws IndexOutOfBoundsException 258 * If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt> 259 * is greater than <tt>end</tt>, or <tt>end</tt> is greater than 260 * <tt>csq.length()</tt> 261 * 262 * @throws IOException 263 * If an I/O error occurs 264 * 265 * @since 1.5 266 */ 267 public Writer append(CharSequence csq, int start, int end) throws IOException { 268 CharSequence cs = (csq == null ? "null" : csq); 269 write(cs.subSequence(start, end).toString()); 270 return this; 271 } 272 273 /** 274 * Appends the specified character to this writer. 275 * 276 * <p> An invocation of this method of the form <tt>out.append(c)</tt> 277 * behaves in exactly the same way as the invocation 278 * 279 * <pre> 280 * out.write(c) </pre> 281 * 282 * @param c 283 * The 16-bit character to append 284 * 285 * @return This writer 286 * 287 * @throws IOException 288 * If an I/O error occurs 289 * 290 * @since 1.5 291 */ 292 public Writer append(char c) throws IOException { 293 write(c); 294 return this; 295 } 296 297 /** 298 * Flushes the stream. If the stream has saved any characters from the 299 * various write() methods in a buffer, write them immediately to their 300 * intended destination. Then, if that destination is another character or 301 * byte stream, flush it. Thus one flush() invocation will flush all the 302 * buffers in a chain of Writers and OutputStreams. 303 * 304 * <p> If the intended destination of this stream is an abstraction provided 305 * by the underlying operating system, for example a file, then flushing the 306 * stream guarantees only that bytes previously written to the stream are 307 * passed to the operating system for writing; it does not guarantee that 308 * they are actually written to a physical device such as a disk drive. 309 * 310 * @throws IOException 311 * If an I/O error occurs 312 */ 313 abstract public void flush() throws IOException; 314 315 /** 316 * Closes the stream, flushing it first. Once the stream has been closed, 317 * further write() or flush() invocations will cause an IOException to be 318 * thrown. Closing a previously closed stream has no effect. 319 * 320 * @throws IOException 321 * If an I/O error occurs 322 */ 323 abstract public void close() throws IOException; 324 325} 326