001 /*
002 * Copyright 1996-2005 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package java.io;
027
028 /**
029 * Abstract class for writing to character streams. The only methods that a
030 * subclass must implement are write(char[], int, int), flush(), and close().
031 * Most subclasses, however, will override some of the methods defined here in
032 * order to provide higher efficiency, additional functionality, or both.
033 *
034 * @see Writer
035 * @see BufferedWriter
036 * @see CharArrayWriter
037 * @see FilterWriter
038 * @see OutputStreamWriter
039 * @see FileWriter
040 * @see PipedWriter
041 * @see PrintWriter
042 * @see StringWriter
043 * @see Reader
044 *
045 * @version 1.35, 07/05/05
046 * @author Mark Reinhold
047 * @since JDK1.1
048 */
049
050 public abstract class Writer implements Appendable, Closeable,
051 Flushable {
052
053 /**
054 * Temporary buffer used to hold writes of strings and single characters
055 */
056 private char[] writeBuffer;
057
058 /**
059 * Size of writeBuffer, must be >= 1
060 */
061 private final int writeBufferSize = 1024;
062
063 /**
064 * The object used to synchronize operations on this stream. For
065 * efficiency, a character-stream object may use an object other than
066 * itself to protect critical sections. A subclass should therefore use
067 * the object in this field rather than <tt>this</tt> or a synchronized
068 * method.
069 */
070 protected Object lock;
071
072 /**
073 * Creates a new character-stream writer whose critical sections will
074 * synchronize on the writer itself.
075 */
076 protected Writer() {
077 this .lock = this ;
078 }
079
080 /**
081 * Creates a new character-stream writer whose critical sections will
082 * synchronize on the given object.
083 *
084 * @param lock
085 * Object to synchronize on
086 */
087 protected Writer(Object lock) {
088 if (lock == null) {
089 throw new NullPointerException();
090 }
091 this .lock = lock;
092 }
093
094 /**
095 * Writes a single character. The character to be written is contained in
096 * the 16 low-order bits of the given integer value; the 16 high-order bits
097 * are ignored.
098 *
099 * <p> Subclasses that intend to support efficient single-character output
100 * should override this method.
101 *
102 * @param c
103 * int specifying a character to be written
104 *
105 * @throws IOException
106 * If an I/O error occurs
107 */
108 public void write(int c) throws IOException {
109 synchronized (lock) {
110 if (writeBuffer == null) {
111 writeBuffer = new char[writeBufferSize];
112 }
113 writeBuffer[0] = (char) c;
114 write(writeBuffer, 0, 1);
115 }
116 }
117
118 /**
119 * Writes an array of characters.
120 *
121 * @param cbuf
122 * Array of characters to be written
123 *
124 * @throws IOException
125 * If an I/O error occurs
126 */
127 public void write(char cbuf[]) throws IOException {
128 write(cbuf, 0, cbuf.length);
129 }
130
131 /**
132 * Writes a portion of an array of characters.
133 *
134 * @param cbuf
135 * Array of characters
136 *
137 * @param off
138 * Offset from which to start writing characters
139 *
140 * @param len
141 * Number of characters to write
142 *
143 * @throws IOException
144 * If an I/O error occurs
145 */
146 abstract public void write(char cbuf[], int off, int len)
147 throws IOException;
148
149 /**
150 * Writes a string.
151 *
152 * @param str
153 * String to be written
154 *
155 * @throws IOException
156 * If an I/O error occurs
157 */
158 public void write(String str) throws IOException {
159 write(str, 0, str.length());
160 }
161
162 /**
163 * Writes a portion of a string.
164 *
165 * @param str
166 * A String
167 *
168 * @param off
169 * Offset from which to start writing characters
170 *
171 * @param len
172 * Number of characters to write
173 *
174 * @throws IndexOutOfBoundsException
175 * If <tt>off</tt> is negative, or <tt>len</tt> is negative,
176 * or <tt>off+len</tt> is negative or greater than the length
177 * of the given string
178 *
179 * @throws IOException
180 * If an I/O error occurs
181 */
182 public void write(String str, int off, int len) throws IOException {
183 synchronized (lock) {
184 char cbuf[];
185 if (len <= writeBufferSize) {
186 if (writeBuffer == null) {
187 writeBuffer = new char[writeBufferSize];
188 }
189 cbuf = writeBuffer;
190 } else { // Don't permanently allocate very large buffers.
191 cbuf = new char[len];
192 }
193 str.getChars(off, (off + len), cbuf, 0);
194 write(cbuf, 0, len);
195 }
196 }
197
198 /**
199 * Appends the specified character sequence to this writer.
200 *
201 * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
202 * behaves in exactly the same way as the invocation
203 *
204 * <pre>
205 * out.write(csq.toString()) </pre>
206 *
207 * <p> Depending on the specification of <tt>toString</tt> for the
208 * character sequence <tt>csq</tt>, the entire sequence may not be
209 * appended. For instance, invoking the <tt>toString</tt> method of a
210 * character buffer will return a subsequence whose content depends upon
211 * the buffer's position and limit.
212 *
213 * @param csq
214 * The character sequence to append. If <tt>csq</tt> is
215 * <tt>null</tt>, then the four characters <tt>"null"</tt> are
216 * appended to this writer.
217 *
218 * @return This writer
219 *
220 * @throws IOException
221 * If an I/O error occurs
222 *
223 * @since 1.5
224 */
225 public Writer append(CharSequence csq) throws IOException {
226 if (csq == null)
227 write("null");
228 else
229 write(csq.toString());
230 return this ;
231 }
232
233 /**
234 * Appends a subsequence of the specified character sequence to this writer.
235 * <tt>Appendable</tt>.
236 *
237 * <p> An invocation of this method of the form <tt>out.append(csq, start,
238 * end)</tt> when <tt>csq</tt> is not <tt>null</tt> behaves in exactly the
239 * same way as the invocation
240 *
241 * <pre>
242 * out.write(csq.subSequence(start, end).toString()) </pre>
243 *
244 * @param csq
245 * The character sequence from which a subsequence will be
246 * appended. If <tt>csq</tt> is <tt>null</tt>, then characters
247 * will be appended as if <tt>csq</tt> contained the four
248 * characters <tt>"null"</tt>.
249 *
250 * @param start
251 * The index of the first character in the subsequence
252 *
253 * @param end
254 * The index of the character following the last character in the
255 * subsequence
256 *
257 * @return This writer
258 *
259 * @throws IndexOutOfBoundsException
260 * If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
261 * is greater than <tt>end</tt>, or <tt>end</tt> is greater than
262 * <tt>csq.length()</tt>
263 *
264 * @throws IOException
265 * If an I/O error occurs
266 *
267 * @since 1.5
268 */
269 public Writer append(CharSequence csq, int start, int end)
270 throws IOException {
271 CharSequence cs = (csq == null ? "null" : csq);
272 write(cs.subSequence(start, end).toString());
273 return this ;
274 }
275
276 /**
277 * Appends the specified character to this writer.
278 *
279 * <p> An invocation of this method of the form <tt>out.append(c)</tt>
280 * behaves in exactly the same way as the invocation
281 *
282 * <pre>
283 * out.write(c) </pre>
284 *
285 * @param c
286 * The 16-bit character to append
287 *
288 * @return This writer
289 *
290 * @throws IOException
291 * If an I/O error occurs
292 *
293 * @since 1.5
294 */
295 public Writer append(char c) throws IOException {
296 write(c);
297 return this ;
298 }
299
300 /**
301 * Flushes the stream. If the stream has saved any characters from the
302 * various write() methods in a buffer, write them immediately to their
303 * intended destination. Then, if that destination is another character or
304 * byte stream, flush it. Thus one flush() invocation will flush all the
305 * buffers in a chain of Writers and OutputStreams.
306 *
307 * <p> If the intended destination of this stream is an abstraction provided
308 * by the underlying operating system, for example a file, then flushing the
309 * stream guarantees only that bytes previously written to the stream are
310 * passed to the operating system for writing; it does not guarantee that
311 * they are actually written to a physical device such as a disk drive.
312 *
313 * @throws IOException
314 * If an I/O error occurs
315 */
316 abstract public void flush() throws IOException;
317
318 /**
319 * Closes the stream, flushing it first. Once the stream has been closed,
320 * further write() or flush() invocations will cause an IOException to be
321 * thrown. Closing a previously closed stream has no effect.
322 *
323 * @throws IOException
324 * If an I/O error occurs
325 */
326 abstract public void close() throws IOException;
327
328 }
|