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 static final String TOKEN_NULL = "null"; //$NON-NLS-1$ 40 41 /** 42 * The object used to synchronize access to the writer. 43 */ 44 protected Object lock; 45 46 /** 47 * Constructs a new {@code Writer} with {@code this} as the object used to 48 * synchronize critical sections. 49 */ 50 protected Writer() { 51 super(); 52 lock = this; 53 } 54 55 /** 56 * Constructs a new {@code Writer} with {@code lock} used to synchronize 57 * critical sections. 58 * 59 * @param lock 60 * the {@code Object} used to synchronize critical sections. 61 * @throws NullPointerException 62 * if {@code lock} is {@code null}. 63 */ 64 protected Writer(Object lock) { 65 if (lock == null) { 66 throw new NullPointerException(); 67 } 68 this.lock = lock; 69 } 70 71 /** 72 * Closes this writer. Implementations of this method should free any 73 * resources associated with the writer. 74 * 75 * @throws IOException 76 * if an error occurs while closing this writer. 77 */ 78 public abstract void close() throws IOException; 79 80 /** 81 * Flushes this writer. Implementations of this method should ensure that 82 * all buffered characters are written to the target. 83 * 84 * @throws IOException 85 * if an error occurs while flushing this writer. 86 */ 87 public abstract void flush() throws IOException; 88 89 /** 90 * Writes the entire character buffer {@code buf} to the target. 91 * 92 * @param buf 93 * the non-null array containing characters to write. 94 * @throws IOException 95 * if this writer is closed or another I/O error occurs. 96 */ 97 public void write(char[] buf) throws IOException { 98 // BEGIN android-note 99 // changed array notation to be consistent with the rest of harmony 100 // END android-note 101 write(buf, 0, buf.length); 102 } 103 104 /** 105 * Writes {@code count} characters starting at {@code offset} in {@code buf} 106 * to the target. 107 * 108 * @param buf 109 * the non-null character array to write. 110 * @param offset 111 * the index of the first character in {@code buf} to write. 112 * @param count 113 * the maximum number of characters to write. 114 * @throws IndexOutOfBoundsException 115 * if {@code offset < 0} or {@code count < 0}, or if {@code 116 * offset + count} is greater than the size of {@code buf}. 117 * @throws IOException 118 * if this writer is closed or another I/O error occurs. 119 */ 120 public abstract void write(char[] buf, int offset, int count) 121 throws IOException; 122 // BEGIN android-note 123 // changed array notation to be consistent with the rest of harmony 124 // END android-note 125 126 /** 127 * Writes one character to the target. Only the two least significant bytes 128 * of the integer {@code oneChar} are written. 129 * 130 * @param oneChar 131 * the character to write to the target. 132 * @throws IOException 133 * if this writer is closed or another I/O error occurs. 134 */ 135 public void write(int oneChar) throws IOException { 136 synchronized (lock) { 137 char oneCharArray[] = new char[1]; 138 oneCharArray[0] = (char) oneChar; 139 write(oneCharArray); 140 } 141 } 142 143 /** 144 * Writes the characters from the specified string to the target. 145 * 146 * @param str 147 * the non-null string containing the characters to write. 148 * @throws IOException 149 * if this writer is closed or another I/O error occurs. 150 */ 151 public void write(String str) throws IOException { 152 write(str, 0, str.length()); 153 } 154 155 /** 156 * Writes {@code count} characters from {@code str} starting at {@code 157 * offset} to the target. 158 * 159 * @param str 160 * the non-null string containing the characters to write. 161 * @param offset 162 * the index of the first character in {@code str} to write. 163 * @param count 164 * the number of characters from {@code str} to write. 165 * @throws IOException 166 * if this writer is closed or another I/O error occurs. 167 * @throws IndexOutOfBoundsException 168 * if {@code offset < 0} or {@code count < 0}, or if {@code 169 * offset + count} is greater than the length of {@code str}. 170 */ 171 public void write(String str, int offset, int count) throws IOException { 172 if (count < 0) { // other cases tested by getChars() 173 throw new StringIndexOutOfBoundsException(); 174 } 175 char buf[] = new char[count]; 176 str.getChars(offset, offset + count, buf, 0); 177 178 synchronized (lock) { 179 write(buf, 0, buf.length); 180 } 181 } 182 183 /** 184 * Appends the character {@code c} to the target. This method works the same 185 * way as {@link #write(int)}. 186 * 187 * @param c 188 * the character to append to the target stream. 189 * @return this writer. 190 * @throws IOException 191 * if this writer is closed or another I/O error occurs. 192 */ 193 public Writer append(char c) throws IOException { 194 write(c); 195 return this; 196 } 197 198 /** 199 * Appends the character sequence {@code csq} to the target. This method 200 * works the same way as {@code Writer.write(csq.toString())}. If {@code 201 * csq} is {@code null}, then the string "null" is written to the target 202 * stream. 203 * 204 * @param csq 205 * the character sequence appended to the target. 206 * @return this writer. 207 * @throws IOException 208 * if this writer is closed or another I/O error occurs. 209 */ 210 public Writer append(CharSequence csq) throws IOException { 211 if (null == csq) { 212 write(TOKEN_NULL); 213 } else { 214 write(csq.toString()); 215 } 216 return this; 217 } 218 219 /** 220 * Appends a subsequence of the character sequence {@code csq} to the 221 * target. This method works the same way as {@code 222 * Writer.writer(csq.subsequence(start, end).toString())}. If {@code 223 * csq} is {@code null}, then the specified subsequence of the string "null" 224 * will be written to the target. 225 * 226 * @param csq 227 * the character sequence appended to the target. 228 * @param start 229 * the index of the first char in the character sequence appended 230 * to the target. 231 * @param end 232 * the index of the character following the last character of the 233 * subsequence appended to the target. 234 * @return this writer. 235 * @throws IOException 236 * if this writer is closed or another I/O error occurs. 237 * @throws IndexOutOfBoundsException 238 * if {@code start > end}, {@code start < 0}, {@code end < 0} or 239 * either {@code start} or {@code end} are greater or equal than 240 * the length of {@code csq}. 241 */ 242 public Writer append(CharSequence csq, int start, int end) 243 throws IOException { 244 if (null == csq) { 245 write(TOKEN_NULL.substring(start, end)); 246 } else { 247 write(csq.subSequence(start, end).toString()); 248 } 249 return this; 250 } 251 252 /** 253 * Returns true if this writer has encountered and suppressed an error. Used 254 * by PrintWriters as an alternative to checked exceptions. 255 */ 256 boolean checkError() { 257 return false; 258 } 259} 260