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 18package 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 */ 37public 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 */ 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 */ 60 protected Writer(Object lock) { 61 if (lock == null) { 62 throw new NullPointerException(); 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 241 boolean checkError() { 242 return false; 243 } 244} 245