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 26 package java.io; 27 28 import java.util.Formatter; 29 import java.util.Locale; 30 31 32 /** 33 * A <code>PrintStream</code> adds functionality to another output stream, 34 * namely the ability to print representations of various data values 35 * conveniently. Two other features are provided as well. Unlike other output 36 * streams, a <code>PrintStream</code> never throws an 37 * <code>IOException</code>; instead, exceptional situations merely set an 38 * internal flag that can be tested via the <code>checkError</code> method. 39 * Optionally, a <code>PrintStream</code> can be created so as to flush 40 * automatically; this means that the <code>flush</code> method is 41 * automatically invoked after a byte array is written, one of the 42 * <code>println</code> methods is invoked, or a newline character or byte 43 * (<code>'\n'</code>) is written. 44 * 45 * <p> All characters printed by a <code>PrintStream</code> are converted into 46 * bytes using the platform's default character encoding. The <code>{@link 47 * PrintWriter}</code> class should be used in situations that require writing 48 * characters rather than bytes. 49 * 50 * @author Frank Yellin 51 * @author Mark Reinhold 52 * @since JDK1.0 53 */ 54 55 public class PrintStream extends FilterOutputStream 56 implements Appendable, Closeable 57 { 58 59 private boolean autoFlush = false; 60 private boolean trouble = false; 61 private Formatter formatter; 62 63 /** 64 * Track both the text- and character-output streams, so that their buffers 65 * can be flushed without flushing the entire stream. 66 */ 67 private BufferedWriter textOut; 68 private OutputStreamWriter charOut; 69 70 /** 71 * Creates a new print stream. This stream will not flush automatically. 72 * 73 * @param out The output stream to which values and objects will be 74 * printed 75 * 76 * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream) 77 */ 78 public PrintStream(OutputStream out) { 79 this(out, false); 80 } 81 82 /* Initialization is factored into a private constructor (note the swapped 83 * parameters so that this one isn't confused with the public one) and a 84 * separate init method so that the following two public constructors can 85 * share code. We use a separate init method so that the constructor that 86 * takes an encoding will throw an NPE for a null stream before it throws 87 * an UnsupportedEncodingException for an unsupported encoding. 88 */ 89 90 private PrintStream(boolean autoFlush, OutputStream out) 91 { 92 super(out); 93 if (out == null) 94 throw new NullPointerException("Null output stream"); 95 this.autoFlush = autoFlush; 96 } 97 98 private void init(OutputStreamWriter osw) { 99 this.charOut = osw; 100 this.textOut = new BufferedWriter(osw); 101 } 102 103 /** 104 * Creates a new print stream. 105 * 106 * @param out The output stream to which values and objects will be 107 * printed 108 * @param autoFlush A boolean; if true, the output buffer will be flushed 109 * whenever a byte array is written, one of the 110 * <code>println</code> methods is invoked, or a newline 111 * character or byte (<code>'\n'</code>) is written 112 * 113 * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean) 114 */ 115 public PrintStream(OutputStream out, boolean autoFlush) { 116 this(autoFlush, out); 117 init(new OutputStreamWriter(this)); 118 } 119 120 /** 121 * Creates a new print stream. 122 * 123 * @param out The output stream to which values and objects will be 124 * printed 125 * @param autoFlush A boolean; if true, the output buffer will be flushed 126 * whenever a byte array is written, one of the 127 * <code>println</code> methods is invoked, or a newline 128 * character or byte (<code>'\n'</code>) is written 129 * @param encoding The name of a supported 130 * <a href="../lang/package-summary.html#charenc"> 131 * character encoding</a> 132 * 133 * @throws UnsupportedEncodingException 134 * If the named encoding is not supported 135 * 136 * @since 1.4 137 */ 138 public PrintStream(OutputStream out, boolean autoFlush, String encoding) 139 throws UnsupportedEncodingException 140 { 141 this(autoFlush, out); 142 init(new OutputStreamWriter(this, encoding)); 143 } 144 145 /** 146 * Creates a new print stream, without automatic line flushing, with the 147 * specified file name. This convenience constructor creates 148 * the necessary intermediate {@link java.io.OutputStreamWriter 149 * OutputStreamWriter}, which will encode characters using the 150 * {@linkplain java.nio.charset.Charset#defaultCharset() default charset} 151 * for this instance of the Java virtual machine. 152 * 153 * @param fileName 154 * The name of the file to use as the destination of this print 155 * stream. If the file exists, then it will be truncated to 156 * zero size; otherwise, a new file will be created. The output 157 * will be written to the file and is buffered. 158 * 159 * @throws FileNotFoundException 160 * If the given file object does not denote an existing, writable 161 * regular file and a new regular file of that name cannot be 162 * created, or if some other error occurs while opening or 163 * creating the file 164 * 165 * @throws SecurityException 166 * If a security manager is present and {@link 167 * SecurityManager#checkWrite checkWrite(fileName)} denies write 168 * access to the file 169 * 170 * @since 1.5 171 */ 172 public PrintStream(String fileName) throws FileNotFoundException { 173 this(false, new FileOutputStream(fileName)); 174 init(new OutputStreamWriter(this)); 175 } 176 177 /** 178 * Creates a new print stream, without automatic line flushing, with the 179 * specified file name and charset. This convenience constructor creates 180 * the necessary intermediate {@link java.io.OutputStreamWriter 181 * OutputStreamWriter}, which will encode characters using the provided 182 * charset. 183 * 184 * @param fileName 185 * The name of the file to use as the destination of this print 186 * stream. If the file exists, then it will be truncated to 187 * zero size; otherwise, a new file will be created. The output 188 * will be written to the file and is buffered. 189 * 190 * @param csn 191 * The name of a supported {@linkplain java.nio.charset.Charset 192 * charset} 193 * 194 * @throws FileNotFoundException 195 * If the given file object does not denote an existing, writable 196 * regular file and a new regular file of that name cannot be 197 * created, or if some other error occurs while opening or 198 * creating the file 199 * 200 * @throws SecurityException 201 * If a security manager is present and {@link 202 * SecurityManager#checkWrite checkWrite(fileName)} denies write 203 * access to the file 204 * 205 * @throws UnsupportedEncodingException 206 * If the named charset is not supported 207 * 208 * @since 1.5 209 */ 210 public PrintStream(String fileName, String csn) 211 throws FileNotFoundException, UnsupportedEncodingException 212 { 213 this(false, new FileOutputStream(fileName)); 214 init(new OutputStreamWriter(this, csn)); 215 } 216 217 /** 218 * Creates a new print stream, without automatic line flushing, with the 219 * specified file. This convenience constructor creates the necessary 220 * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter}, 221 * which will encode characters using the {@linkplain 222 * java.nio.charset.Charset#defaultCharset() default charset} for this 223 * instance of the Java virtual machine. 224 * 225 * @param file 226 * The file to use as the destination of this print stream. If the 227 * file exists, then it will be truncated to zero size; otherwise, 228 * a new file will be created. The output will be written to the 229 * file and is buffered. 230 * 231 * @throws FileNotFoundException 232 * If the given file object does not denote an existing, writable 233 * regular file and a new regular file of that name cannot be 234 * created, or if some other error occurs while opening or 235 * creating the file 236 * 237 * @throws SecurityException 238 * If a security manager is present and {@link 239 * SecurityManager#checkWrite checkWrite(file.getPath())} 240 * denies write access to the file 241 * 242 * @since 1.5 243 */ 244 public PrintStream(File file) throws FileNotFoundException { 245 this(false, new FileOutputStream(file)); 246 init(new OutputStreamWriter(this)); 247 } 248 249 /** 250 * Creates a new print stream, without automatic line flushing, with the 251 * specified file and charset. This convenience constructor creates 252 * the necessary intermediate {@link java.io.OutputStreamWriter 253 * OutputStreamWriter}, which will encode characters using the provided 254 * charset. 255 * 256 * @param file 257 * The file to use as the destination of this print stream. If the 258 * file exists, then it will be truncated to zero size; otherwise, 259 * a new file will be created. The output will be written to the 260 * file and is buffered. 261 * 262 * @param csn 263 * The name of a supported {@linkplain java.nio.charset.Charset 264 * charset} 265 * 266 * @throws FileNotFoundException 267 * If the given file object does not denote an existing, writable 268 * regular file and a new regular file of that name cannot be 269 * created, or if some other error occurs while opening or 270 * creating the file 271 * 272 * @throws SecurityException 273 * If a security manager is presentand {@link 274 * SecurityManager#checkWrite checkWrite(file.getPath())} 275 * denies write access to the file 276 * 277 * @throws UnsupportedEncodingException 278 * If the named charset is not supported 279 * 280 * @since 1.5 281 */ 282 public PrintStream(File file, String csn) 283 throws FileNotFoundException, UnsupportedEncodingException 284 { 285 this(false, new FileOutputStream(file)); 286 init(new OutputStreamWriter(this, csn)); 287 } 288 289 /** Check to make sure that the stream has not been closed */ 290 private void ensureOpen() throws IOException { 291 if (out == null) 292 throw new IOException("Stream closed"); 293 } 294 295 /** 296 * Flushes the stream. This is done by writing any buffered output bytes to 297 * the underlying output stream and then flushing that stream. 298 * 299 * @see java.io.OutputStream#flush() 300 */ 301 public void flush() { 302 synchronized (this) { 303 try { 304 ensureOpen(); 305 out.flush(); 306 } | 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 26 package java.io; 27 28 import java.util.Formatter; 29 import java.util.Locale; 30 import java.nio.charset.Charset; 31 import java.nio.charset.IllegalCharsetNameException; 32 33 /** 34 * A <code>PrintStream</code> adds functionality to another output stream, 35 * namely the ability to print representations of various data values 36 * conveniently. Two other features are provided as well. Unlike other output 37 * streams, a <code>PrintStream</code> never throws an 38 * <code>IOException</code>; instead, exceptional situations merely set an 39 * internal flag that can be tested via the <code>checkError</code> method. 40 * Optionally, a <code>PrintStream</code> can be created so as to flush 41 * automatically; this means that the <code>flush</code> method is 42 * automatically invoked after a byte array is written, one of the 43 * <code>println</code> methods is invoked, or a newline character or byte 44 * (<code>'\n'</code>) is written. 45 * 46 * <p> All characters printed by a <code>PrintStream</code> are converted into 47 * bytes using the platform's default character encoding. The <code>{@link 48 * PrintWriter}</code> class should be used in situations that require writing 49 * characters rather than bytes. 50 * 51 * @author Frank Yellin 52 * @author Mark Reinhold 53 * @since JDK1.0 54 */ 55 56 public class PrintStream extends FilterOutputStream 57 implements Appendable, Closeable 58 { 59 60 private final boolean autoFlush; 61 private boolean trouble = false; 62 private Formatter formatter; 63 64 /** 65 * Track both the text- and character-output streams, so that their buffers 66 * can be flushed without flushing the entire stream. 67 */ 68 private BufferedWriter textOut; 69 private OutputStreamWriter charOut; 70 71 /** 72 * nonNull is explicitly delcared here so as not to create an extra 73 * dependency on java.util.Objects.nonNull. PrintStream is loaded 74 * early during system initialization. 75 */ 76 private static <T> T nonNull(T obj, String message) { 77 if (obj == null) 78 throw new NullPointerException(message); 79 return obj; 80 } 81 82 /** 83 * Returns the given charset name if it is supported. 84 * @throws NullPointerException is csn is null 85 * @throws UnsupportedEncodingException if the charset is not supported 86 */ 87 private static String verifyCharsetName(String csn) 88 throws UnsupportedEncodingException { 89 nonNull(csn, "charsetName"); 90 try { 91 if (Charset.isSupported(csn)) 92 return csn; 93 } catch (IllegalCharsetNameException unused) { 94 /* swallow this exception since UnsupportedEncodingException 95 * will be thrown */ 96 } 97 throw new UnsupportedEncodingException(csn); 98 } 99 100 /* Private constructors */ 101 private PrintStream(boolean autoFlush, OutputStream out) { 102 super(out); 103 this.autoFlush = autoFlush; 104 this.charOut = new OutputStreamWriter(this); 105 this.textOut = new BufferedWriter(charOut); 106 } 107 108 private PrintStream(boolean autoFlush, OutputStream out, String csn) 109 throws UnsupportedEncodingException { 110 super(out); 111 this.autoFlush = autoFlush; 112 this.charOut = new OutputStreamWriter(this, csn); 113 this.textOut = new BufferedWriter(charOut); 114 } 115 116 /* Variant of the private constructor so that the given charset name 117 * can be verified before evaluating the OutputStream argument. Used 118 * by constructors creating a FileOutputStream that also take a 119 * charset name. 120 */ 121 private PrintStream(boolean autoFlush, String csn, OutputStream out) 122 throws UnsupportedEncodingException { 123 this(autoFlush, out, csn); 124 } 125 126 /** 127 * Creates a new print stream. This stream will not flush automatically. 128 * 129 * @param out The output stream to which values and objects will be 130 * printed 131 * 132 * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream) 133 */ 134 public PrintStream(OutputStream out) { 135 this(out, false); 136 } 137 138 /** 139 * Creates a new print stream. 140 * 141 * @param out The output stream to which values and objects will be 142 * printed 143 * @param autoFlush A boolean; if true, the output buffer will be flushed 144 * whenever a byte array is written, one of the 145 * <code>println</code> methods is invoked, or a newline 146 * character or byte (<code>'\n'</code>) is written 147 * 148 * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean) 149 */ 150 public PrintStream(OutputStream out, boolean autoFlush) { 151 this(autoFlush, nonNull(out, "Null output stream")); 152 } 153 154 /** 155 * Creates a new print stream. 156 * 157 * @param out The output stream to which values and objects will be 158 * printed 159 * @param autoFlush A boolean; if true, the output buffer will be flushed 160 * whenever a byte array is written, one of the 161 * <code>println</code> methods is invoked, or a newline 162 * character or byte (<code>'\n'</code>) is written 163 * @param encoding The name of a supported 164 * <a href="../lang/package-summary.html#charenc"> 165 * character encoding</a> 166 * 167 * @throws UnsupportedEncodingException 168 * If the named encoding is not supported 169 * 170 * @since 1.4 171 */ 172 public PrintStream(OutputStream out, boolean autoFlush, String encoding) 173 throws UnsupportedEncodingException 174 { 175 /* this(boolean,OutputStream,String) is invoked so that the 176 * OutputStream argument can be validated before the charset name. 177 */ 178 this(autoFlush, 179 nonNull(out, "Null output stream"), 180 verifyCharsetName(encoding)); 181 } 182 183 /** 184 * Creates a new print stream, without automatic line flushing, with the 185 * specified file name. This convenience constructor creates 186 * the necessary intermediate {@link java.io.OutputStreamWriter 187 * OutputStreamWriter}, which will encode characters using the 188 * {@linkplain java.nio.charset.Charset#defaultCharset() default charset} 189 * for this instance of the Java virtual machine. 190 * 191 * @param fileName 192 * The name of the file to use as the destination of this print 193 * stream. If the file exists, then it will be truncated to 194 * zero size; otherwise, a new file will be created. The output 195 * will be written to the file and is buffered. 196 * 197 * @throws FileNotFoundException 198 * If the given file object does not denote an existing, writable 199 * regular file and a new regular file of that name cannot be 200 * created, or if some other error occurs while opening or 201 * creating the file 202 * 203 * @throws SecurityException 204 * If a security manager is present and {@link 205 * SecurityManager#checkWrite checkWrite(fileName)} denies write 206 * access to the file 207 * 208 * @since 1.5 209 */ 210 public PrintStream(String fileName) throws FileNotFoundException { 211 this(false, new FileOutputStream(fileName)); 212 } 213 214 /** 215 * Creates a new print stream, without automatic line flushing, with the 216 * specified file name and charset. This convenience constructor creates 217 * the necessary intermediate {@link java.io.OutputStreamWriter 218 * OutputStreamWriter}, which will encode characters using the provided 219 * charset. 220 * 221 * @param fileName 222 * The name of the file to use as the destination of this print 223 * stream. If the file exists, then it will be truncated to 224 * zero size; otherwise, a new file will be created. The output 225 * will be written to the file and is buffered. 226 * 227 * @param csn 228 * The name of a supported {@linkplain java.nio.charset.Charset 229 * charset} 230 * 231 * @throws FileNotFoundException 232 * If the given file object does not denote an existing, writable 233 * regular file and a new regular file of that name cannot be 234 * created, or if some other error occurs while opening or 235 * creating the file 236 * 237 * @throws SecurityException 238 * If a security manager is present and {@link 239 * SecurityManager#checkWrite checkWrite(fileName)} denies write 240 * access to the file 241 * 242 * @throws UnsupportedEncodingException 243 * If the named charset is not supported 244 * 245 * @since 1.5 246 */ 247 public PrintStream(String fileName, String csn) 248 throws FileNotFoundException, UnsupportedEncodingException 249 { 250 /* this(boolean,String,OutputStream) is invoked so that the 251 * charset name can be verified before creating an output 252 * stream to the file. */ 253 this(false, verifyCharsetName(csn), new FileOutputStream(fileName)); 254 } 255 256 /** 257 * Creates a new print stream, without automatic line flushing, with the 258 * specified file. This convenience constructor creates the necessary 259 * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter}, 260 * which will encode characters using the {@linkplain 261 * java.nio.charset.Charset#defaultCharset() default charset} for this 262 * instance of the Java virtual machine. 263 * 264 * @param file 265 * The file to use as the destination of this print stream. If the 266 * file exists, then it will be truncated to zero size; otherwise, 267 * a new file will be created. The output will be written to the 268 * file and is buffered. 269 * 270 * @throws FileNotFoundException 271 * If the given file object does not denote an existing, writable 272 * regular file and a new regular file of that name cannot be 273 * created, or if some other error occurs while opening or 274 * creating the file 275 * 276 * @throws SecurityException 277 * If a security manager is present and {@link 278 * SecurityManager#checkWrite checkWrite(file.getPath())} 279 * denies write access to the file 280 * 281 * @since 1.5 282 */ 283 public PrintStream(File file) throws FileNotFoundException { 284 this(false, new FileOutputStream(file)); 285 } 286 287 /** 288 * Creates a new print stream, without automatic line flushing, with the 289 * specified file and charset. This convenience constructor creates 290 * the necessary intermediate {@link java.io.OutputStreamWriter 291 * OutputStreamWriter}, which will encode characters using the provided 292 * charset. 293 * 294 * @param file 295 * The file to use as the destination of this print stream. If the 296 * file exists, then it will be truncated to zero size; otherwise, 297 * a new file will be created. The output will be written to the 298 * file and is buffered. 299 * 300 * @param csn 301 * The name of a supported {@linkplain java.nio.charset.Charset 302 * charset} 303 * 304 * @throws FileNotFoundException 305 * If the given file object does not denote an existing, writable 306 * regular file and a new regular file of that name cannot be 307 * created, or if some other error occurs while opening or 308 * creating the file 309 * 310 * @throws SecurityException 311 * If a security manager is presentand {@link 312 * SecurityManager#checkWrite checkWrite(file.getPath())} 313 * denies write access to the file 314 * 315 * @throws UnsupportedEncodingException 316 * If the named charset is not supported 317 * 318 * @since 1.5 319 */ 320 public PrintStream(File file, String csn) 321 throws FileNotFoundException, UnsupportedEncodingException 322 { 323 /* this(boolean,String,OutputStream) is invoked so that the 324 * charset name can be verified before creating an output 325 * stream to the file. */ 326 this(false, verifyCharsetName(csn), new FileOutputStream(file)); 327 } 328 329 /** Check to make sure that the stream has not been closed */ 330 private void ensureOpen() throws IOException { 331 if (out == null) 332 throw new IOException("Stream closed"); 333 } 334 335 /** 336 * Flushes the stream. This is done by writing any buffered output bytes to 337 * the underlying output stream and then flushing that stream. 338 * 339 * @see java.io.OutputStream#flush() 340 */ 341 public void flush() { 342 synchronized (this) { 343 try { 344 ensureOpen(); 345 out.flush(); 346 } |