• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
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.
16  */
17 
18 package java.io;
19 
20 /**
21  * The base class for all writers. A writer is a means of writing data to a
22  * target in a character-wise manner. Most output streams expect the
23  * {@link #flush()} method to be called before closing the stream, to ensure all
24  * data is actually written out.
25  * <p>
26  * This abstract class does not provide a fully working implementation, so it
27  * needs to be subclassed, and at least the {@link #write(char[], int, int)},
28  * {@link #close()} and {@link #flush()} methods needs to be overridden.
29  * Overriding some of the non-abstract methods is also often advised, since it
30  * might result in higher efficiency.
31  * <p>
32  * Many specialized readers for purposes like reading from a file already exist
33  * in this package.
34  *
35  * @see Reader
36  */
37 public abstract class Writer implements Appendable, Closeable, Flushable {
38     /**
39      * The object used to synchronize access to the writer.
40      */
41     protected Object lock;
42 
43     /**
44      * Constructs a new {@code Writer} with {@code this} as the object used to
45      * synchronize critical sections.
46      */
Writer()47     protected Writer() {
48         lock = this;
49     }
50 
51     /**
52      * Constructs a new {@code Writer} with {@code lock} used to synchronize
53      * critical sections.
54      *
55      * @param lock
56      *            the {@code Object} used to synchronize critical sections.
57      * @throws NullPointerException
58      *             if {@code lock} is {@code null}.
59      */
Writer(Object lock)60     protected Writer(Object lock) {
61         if (lock == null) {
62             throw new NullPointerException("lock == null");
63         }
64         this.lock = lock;
65     }
66 
67     /**
68      * Closes this writer. Implementations of this method should free any
69      * resources associated with the writer.
70      *
71      * @throws IOException
72      *             if an error occurs while closing this writer.
73      */
close()74     public abstract void close() throws IOException;
75 
76     /**
77      * Flushes this writer. Implementations of this method should ensure that
78      * all buffered characters are written to the target.
79      *
80      * @throws IOException
81      *             if an error occurs while flushing this writer.
82      */
flush()83     public abstract void flush() throws IOException;
84 
85     /**
86      * Writes the entire character buffer {@code buf} to the target.
87      *
88      * @param buf
89      *            the non-null array containing characters to write.
90      * @throws IOException
91      *             if this writer is closed or another I/O error occurs.
92      */
write(char[] buf)93     public void write(char[] buf) throws IOException {
94         write(buf, 0, buf.length);
95     }
96 
97     /**
98      * Writes {@code count} characters starting at {@code offset} in {@code buf}
99      * to the target.
100      *
101      * @param buf
102      *            the non-null character array to write.
103      * @param offset
104      *            the index of the first character in {@code buf} to write.
105      * @param count
106      *            the maximum number of characters to write.
107      * @throws IndexOutOfBoundsException
108      *             if {@code offset < 0} or {@code count < 0}, or if {@code
109      *             offset + count} is greater than the size of {@code buf}.
110      * @throws IOException
111      *             if this writer is closed or another I/O error occurs.
112      */
write(char[] buf, int offset, int count)113     public abstract void write(char[] buf, int offset, int count) throws IOException;
114 
115     /**
116      * Writes one character to the target. Only the two least significant bytes
117      * of the integer {@code oneChar} are written.
118      *
119      * @param oneChar
120      *            the character to write to the target.
121      * @throws IOException
122      *             if this writer is closed or another I/O error occurs.
123      */
write(int oneChar)124     public void write(int oneChar) throws IOException {
125         synchronized (lock) {
126             char[] oneCharArray = new char[1];
127             oneCharArray[0] = (char) oneChar;
128             write(oneCharArray);
129         }
130     }
131 
132     /**
133      * Writes the characters from the specified string to the target.
134      *
135      * @param str
136      *            the non-null string containing the characters to write.
137      * @throws IOException
138      *             if this writer is closed or another I/O error occurs.
139      */
write(String str)140     public void write(String str) throws IOException {
141         write(str, 0, str.length());
142     }
143 
144     /**
145      * Writes {@code count} characters from {@code str} starting at {@code
146      * offset} to the target.
147      *
148      * @param str
149      *            the non-null string containing the characters to write.
150      * @param offset
151      *            the index of the first character in {@code str} to write.
152      * @param count
153      *            the number of characters from {@code str} to write.
154      * @throws IOException
155      *             if this writer is closed or another I/O error occurs.
156      * @throws IndexOutOfBoundsException
157      *             if {@code offset < 0} or {@code count < 0}, or if {@code
158      *             offset + count} is greater than the length of {@code str}.
159      */
write(String str, int offset, int count)160     public void write(String str, int offset, int count) throws IOException {
161         if ((offset | count) < 0 || offset > str.length() - count) {
162             throw new StringIndexOutOfBoundsException(str, offset, count);
163         }
164         char[] buf = new char[count];
165         str.getChars(offset, offset + count, buf, 0);
166         synchronized (lock) {
167             write(buf, 0, buf.length);
168         }
169     }
170 
171     /**
172      * Appends the character {@code c} to the target. This method works the same
173      * way as {@link #write(int)}.
174      *
175      * @param c
176      *            the character to append to the target stream.
177      * @return this writer.
178      * @throws IOException
179      *             if this writer is closed or another I/O error occurs.
180      */
append(char c)181     public Writer append(char c) throws IOException {
182         write(c);
183         return this;
184     }
185 
186     /**
187      * Appends the character sequence {@code csq} to the target. This method
188      * works the same way as {@code Writer.write(csq.toString())}. If {@code
189      * csq} is {@code null}, then the string "null" is written to the target
190      * stream.
191      *
192      * @param csq
193      *            the character sequence appended to the target.
194      * @return this writer.
195      * @throws IOException
196      *             if this writer is closed or another I/O error occurs.
197      */
append(CharSequence csq)198     public Writer append(CharSequence csq) throws IOException {
199         if (csq == null) {
200             csq = "null";
201         }
202         write(csq.toString());
203         return this;
204     }
205 
206     /**
207      * Appends a subsequence of the character sequence {@code csq} to the
208      * target. This method works the same way as {@code
209      * Writer.writer(csq.subsequence(start, end).toString())}. If {@code
210      * csq} is {@code null}, then the specified subsequence of the string "null"
211      * will be written to the target.
212      *
213      * @param csq
214      *            the character sequence appended to the target.
215      * @param start
216      *            the index of the first char in the character sequence appended
217      *            to the target.
218      * @param end
219      *            the index of the character following the last character of the
220      *            subsequence appended to the target.
221      * @return this writer.
222      * @throws IOException
223      *             if this writer is closed or another I/O error occurs.
224      * @throws IndexOutOfBoundsException
225      *             if {@code start > end}, {@code start < 0}, {@code end < 0} or
226      *             either {@code start} or {@code end} are greater or equal than
227      *             the length of {@code csq}.
228      */
append(CharSequence csq, int start, int end)229     public Writer append(CharSequence csq, int start, int end) throws IOException {
230         if (csq == null) {
231             csq = "null";
232         }
233         write(csq.subSequence(start, end).toString());
234         return this;
235     }
236 
237     /**
238      * Returns true if this writer has encountered and suppressed an error. Used
239      * by PrintWriters as an alternative to checked exceptions.
240      */
checkError()241     boolean checkError() {
242         return false;
243     }
244 }
245