1 /*
2 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
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
28 import java.util.Formatter;
29 import java.util.Locale;
30 import java.nio.charset.Charset;
31 import java.nio.charset.IllegalCharsetNameException;
32 import java.nio.charset.UnsupportedCharsetException;
33
34 /**
35 * A {@code PrintStream} adds functionality to another output stream,
36 * namely the ability to print representations of various data values
37 * conveniently. Two other features are provided as well. Unlike other output
38 * streams, a {@code PrintStream} never throws an
39 * {@code IOException}; instead, exceptional situations merely set an
40 * internal flag that can be tested via the {@code checkError} method.
41 * Optionally, a {@code PrintStream} can be created so as to flush
42 * automatically; this means that the {@code flush} method is
43 * automatically invoked after a byte array is written, one of the
44 * {@code println} methods is invoked, or a newline character or byte
45 * ({@code '\n'}) is written.
46 *
47 * <p> All characters printed by a {@code PrintStream} are converted into
48 * bytes using the platform's default character encoding.
49 * The {@link PrintWriter} class should be used in situations that require
50 * writing characters rather than bytes.
51 *
52 * @author Frank Yellin
53 * @author Mark Reinhold
54 * @since 1.0
55 */
56
57 public class PrintStream extends FilterOutputStream
58 implements Appendable, Closeable
59 {
60
61 private final boolean autoFlush;
62 private boolean trouble = false;
63 private Formatter formatter;
64
65 /**
66 * Track both the text- and character-output streams, so that their buffers
67 * can be flushed without flushing the entire stream.
68 */
69 private BufferedWriter textOut;
70 private OutputStreamWriter charOut;
71
88 private static Charset toCharset(String csn)
89 throws UnsupportedEncodingException
90 {
91 requireNonNull(csn, "charsetName");
92 try {
93 return Charset.forName(csn);
94 } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
95 // UnsupportedEncodingException should be thrown
96 throw new UnsupportedEncodingException(csn);
97 }
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, Charset charset) {
109 super(out);
110 this.autoFlush = autoFlush;
111 this.charOut = new OutputStreamWriter(this, charset);
112 this.textOut = new BufferedWriter(charOut);
113 }
114
115 /* Variant of the private constructor so that the given charset name
116 * can be verified before evaluating the OutputStream argument. Used
117 * by constructors creating a FileOutputStream that also take a
118 * charset name.
119 */
120 private PrintStream(boolean autoFlush, Charset charset, OutputStream out)
121 throws UnsupportedEncodingException
122 {
123 this(autoFlush, out, charset);
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
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} methods is invoked, or a newline
162 * character or byte ({@code '\n'}) 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(autoFlush,
176 requireNonNull(out, "Null output stream"),
177 toCharset(encoding));
178 }
179
180 /**
181 * Creates a new print stream, without automatic line flushing, with the
182 * specified file name. This convenience constructor creates
183 * the necessary intermediate {@link java.io.OutputStreamWriter
184 * OutputStreamWriter}, which will encode characters using the
185 * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}
186 * for this instance of the Java virtual machine.
187 *
188 * @param fileName
189 * The name of the file to use as the destination of this print
190 * stream. If the file exists, then it will be truncated to
191 * zero size; otherwise, a new file will be created. The output
192 * will be written to the file and is buffered.
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
233 *
234 * @throws SecurityException
235 * If a security manager is present and {@link
236 * SecurityManager#checkWrite checkWrite(fileName)} denies write
237 * access to the file
238 *
239 * @throws UnsupportedEncodingException
240 * If the named charset is not supported
241 *
242 * @since 1.5
243 */
244 public PrintStream(String fileName, String csn)
245 throws FileNotFoundException, UnsupportedEncodingException
246 {
247 // ensure charset is checked before the file is opened
248 this(false, toCharset(csn), new FileOutputStream(fileName));
249 }
250
251 /**
252 * Creates a new print stream, without automatic line flushing, with the
253 * specified file. This convenience constructor creates the necessary
254 * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
255 * which will encode characters using the {@linkplain
256 * java.nio.charset.Charset#defaultCharset() default charset} for this
257 * instance of the Java virtual machine.
258 *
259 * @param file
260 * The file to use as the destination of this print stream. If the
261 * file exists, then it will be truncated to zero size; otherwise,
262 * a new file will be created. The output will be written to the
263 * file and is buffered.
264 *
265 * @throws FileNotFoundException
266 * If the given file object does not denote an existing, writable
267 * regular file and a new regular file of that name cannot be
268 * created, or if some other error occurs while opening or
269 * creating the file
270 *
271 * @throws SecurityException
272 * If a security manager is present and {@link
300 * If the given file object does not denote an existing, writable
301 * regular file and a new regular file of that name cannot be
302 * created, or if some other error occurs while opening or
303 * creating the file
304 *
305 * @throws SecurityException
306 * If a security manager is present and {@link
307 * SecurityManager#checkWrite checkWrite(file.getPath())}
308 * denies write access to the file
309 *
310 * @throws UnsupportedEncodingException
311 * If the named charset is not supported
312 *
313 * @since 1.5
314 */
315 public PrintStream(File file, String csn)
316 throws FileNotFoundException, UnsupportedEncodingException
317 {
318 // ensure charset is checked before the file is opened
319 this(false, toCharset(csn), new FileOutputStream(file));
320 }
321
322 /** Check to make sure that the stream has not been closed */
323 private void ensureOpen() throws IOException {
324 if (out == null)
325 throw new IOException("Stream closed");
326 }
327
328 /**
329 * Flushes the stream. This is done by writing any buffered output bytes to
330 * the underlying output stream and then flushing that stream.
331 *
332 * @see java.io.OutputStream#flush()
333 */
334 public void flush() {
335 synchronized (this) {
336 try {
337 ensureOpen();
338 out.flush();
339 }
|
1 /*
2 * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
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
28 import java.util.Formatter;
29 import java.util.Locale;
30 import java.nio.charset.Charset;
31 import java.nio.charset.IllegalCharsetNameException;
32 import java.nio.charset.UnsupportedCharsetException;
33
34 /**
35 * A {@code PrintStream} adds functionality to another output stream,
36 * namely the ability to print representations of various data values
37 * conveniently. Two other features are provided as well. Unlike other output
38 * streams, a {@code PrintStream} never throws an
39 * {@code IOException}; instead, exceptional situations merely set an
40 * internal flag that can be tested via the {@code checkError} method.
41 * Optionally, a {@code PrintStream} can be created so as to flush
42 * automatically; this means that the {@code flush} method is
43 * automatically invoked after a byte array is written, one of the
44 * {@code println} methods is invoked, or a newline character or byte
45 * ({@code '\n'}) is written.
46 *
47 * <p> All characters printed by a {@code PrintStream} are converted into
48 * bytes using the given encoding or charset, or platform's default character
49 * encoding if not specified.
50 * The {@link PrintWriter} class should be used in situations that require
51 * writing characters rather than bytes.
52 *
53 * <p> This class always replaces malformed and unmappable character sequences with
54 * the charset's default replacement string.
55 * The {@linkplain java.nio.charset.CharsetEncoder} class should be used when more
56 * control over the encoding process is required.
57 *
58 * @author Frank Yellin
59 * @author Mark Reinhold
60 * @since 1.0
61 */
62
63 public class PrintStream extends FilterOutputStream
64 implements Appendable, Closeable
65 {
66
67 private final boolean autoFlush;
68 private boolean trouble = false;
69 private Formatter formatter;
70
71 /**
72 * Track both the text- and character-output streams, so that their buffers
73 * can be flushed without flushing the entire stream.
74 */
75 private BufferedWriter textOut;
76 private OutputStreamWriter charOut;
77
94 private static Charset toCharset(String csn)
95 throws UnsupportedEncodingException
96 {
97 requireNonNull(csn, "charsetName");
98 try {
99 return Charset.forName(csn);
100 } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
101 // UnsupportedEncodingException should be thrown
102 throw new UnsupportedEncodingException(csn);
103 }
104 }
105
106 /* Private constructors */
107 private PrintStream(boolean autoFlush, OutputStream out) {
108 super(out);
109 this.autoFlush = autoFlush;
110 this.charOut = new OutputStreamWriter(this);
111 this.textOut = new BufferedWriter(charOut);
112 }
113
114 /* Variant of the private constructor so that the given charset name
115 * can be verified before evaluating the OutputStream argument. Used
116 * by constructors creating a FileOutputStream that also take a
117 * charset name.
118 */
119 private PrintStream(boolean autoFlush, Charset charset, OutputStream out) {
120 this(out, autoFlush, charset);
121 }
122
123 /**
124 * Creates a new print stream. This stream will not flush automatically.
125 *
126 * @param out The output stream to which values and objects will be
127 * printed
128 *
129 * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
130 */
131 public PrintStream(OutputStream out) {
132 this(out, false);
133 }
134
135 /**
136 * Creates a new print stream.
137 *
138 * @param out The output stream to which values and objects will be
139 * printed
140 * @param autoFlush A boolean; if true, the output buffer will be flushed
152 * Creates a new print stream.
153 *
154 * @param out The output stream to which values and objects will be
155 * printed
156 * @param autoFlush A boolean; if true, the output buffer will be flushed
157 * whenever a byte array is written, one of the
158 * {@code println} methods is invoked, or a newline
159 * character or byte ({@code '\n'}) is written
160 * @param encoding The name of a supported
161 * <a href="../lang/package-summary.html#charenc">
162 * character encoding</a>
163 *
164 * @throws UnsupportedEncodingException
165 * If the named encoding is not supported
166 *
167 * @since 1.4
168 */
169 public PrintStream(OutputStream out, boolean autoFlush, String encoding)
170 throws UnsupportedEncodingException
171 {
172 this(requireNonNull(out, "Null output stream"), autoFlush, toCharset(encoding));
173 }
174
175 /**
176 * Creates a new print stream, with the specified OutputStream, automatic line
177 * flushing and charset. This convenience constructor creates the necessary
178 * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
179 * which will encode characters using the provided charset.
180 *
181 * @param out The output stream to which values and objects will be
182 * printed
183 * @param autoFlush A boolean; if true, the output buffer will be flushed
184 * whenever a byte array is written, one of the
185 * {@code println} methods is invoked, or a newline
186 * character or byte ({@code '\n'}) is written
187 * @param charset A {@linkplain java.nio.charset.Charset charset}
188 *
189 * @since 10
190 */
191 public PrintStream(OutputStream out, boolean autoFlush, Charset charset) {
192 super(out);
193 this.autoFlush = autoFlush;
194 this.charOut = new OutputStreamWriter(this, charset);
195 this.textOut = new BufferedWriter(charOut);
196 }
197
198 /**
199 * Creates a new print stream, without automatic line flushing, with the
200 * specified file name. This convenience constructor creates
201 * the necessary intermediate {@link java.io.OutputStreamWriter
202 * OutputStreamWriter}, which will encode characters using the
203 * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}
204 * for this instance of the Java virtual machine.
205 *
206 * @param fileName
207 * The name of the file to use as the destination of this print
208 * stream. If the file exists, then it will be truncated to
209 * zero size; otherwise, a new file will be created. The output
210 * will be written to the file and is buffered.
211 *
212 * @throws FileNotFoundException
213 * If the given file object does not denote an existing, writable
214 * regular file and a new regular file of that name cannot be
215 * created, or if some other error occurs while opening or
251 *
252 * @throws SecurityException
253 * If a security manager is present and {@link
254 * SecurityManager#checkWrite checkWrite(fileName)} denies write
255 * access to the file
256 *
257 * @throws UnsupportedEncodingException
258 * If the named charset is not supported
259 *
260 * @since 1.5
261 */
262 public PrintStream(String fileName, String csn)
263 throws FileNotFoundException, UnsupportedEncodingException
264 {
265 // ensure charset is checked before the file is opened
266 this(false, toCharset(csn), new FileOutputStream(fileName));
267 }
268
269 /**
270 * Creates a new print stream, without automatic line flushing, with the
271 * specified file name and charset. This convenience constructor creates
272 * the necessary intermediate {@link java.io.OutputStreamWriter
273 * OutputStreamWriter}, which will encode characters using the provided
274 * charset.
275 *
276 * @param fileName
277 * The name of the file to use as the destination of this print
278 * stream. If the file exists, then it will be truncated to
279 * zero size; otherwise, a new file will be created. The output
280 * will be written to the file and is buffered.
281 *
282 * @param charset
283 * A {@linkplain java.nio.charset.Charset charset}
284 *
285 * @throws IOException
286 * if an I/O error occurs while opening or creating the file
287 *
288 * @throws SecurityException
289 * If a security manager is present and {@link
290 * SecurityManager#checkWrite checkWrite(fileName)} denies write
291 * access to the file
292 *
293 * @since 10
294 */
295 public PrintStream(String fileName, Charset charset) throws IOException {
296 this(false, requireNonNull(charset, "charset"), new FileOutputStream(fileName));
297 }
298
299 /**
300 * Creates a new print stream, without automatic line flushing, with the
301 * specified file. This convenience constructor creates the necessary
302 * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
303 * which will encode characters using the {@linkplain
304 * java.nio.charset.Charset#defaultCharset() default charset} for this
305 * instance of the Java virtual machine.
306 *
307 * @param file
308 * The file to use as the destination of this print stream. If the
309 * file exists, then it will be truncated to zero size; otherwise,
310 * a new file will be created. The output will be written to the
311 * file and is buffered.
312 *
313 * @throws FileNotFoundException
314 * If the given file object does not denote an existing, writable
315 * regular file and a new regular file of that name cannot be
316 * created, or if some other error occurs while opening or
317 * creating the file
318 *
319 * @throws SecurityException
320 * If a security manager is present and {@link
348 * If the given file object does not denote an existing, writable
349 * regular file and a new regular file of that name cannot be
350 * created, or if some other error occurs while opening or
351 * creating the file
352 *
353 * @throws SecurityException
354 * If a security manager is present and {@link
355 * SecurityManager#checkWrite checkWrite(file.getPath())}
356 * denies write access to the file
357 *
358 * @throws UnsupportedEncodingException
359 * If the named charset is not supported
360 *
361 * @since 1.5
362 */
363 public PrintStream(File file, String csn)
364 throws FileNotFoundException, UnsupportedEncodingException
365 {
366 // ensure charset is checked before the file is opened
367 this(false, toCharset(csn), new FileOutputStream(file));
368 }
369
370
371 /**
372 * Creates a new print stream, without automatic line flushing, with the
373 * specified file and charset. This convenience constructor creates
374 * the necessary intermediate {@link java.io.OutputStreamWriter
375 * OutputStreamWriter}, which will encode characters using the provided
376 * charset.
377 *
378 * @param file
379 * The file to use as the destination of this print stream. If the
380 * file exists, then it will be truncated to zero size; otherwise,
381 * a new file will be created. The output will be written to the
382 * file and is buffered.
383 *
384 * @param charset
385 * A {@linkplain java.nio.charset.Charset charset}
386 *
387 * @throws IOException
388 * if an I/O error occurs while opening or creating the file
389 *
390 * @throws SecurityException
391 * If a security manager is present and {@link
392 * SecurityManager#checkWrite checkWrite(file.getPath())}
393 * denies write access to the file
394 *
395 * @since 10
396 */
397 public PrintStream(File file, Charset charset) throws IOException {
398 this(false, requireNonNull(charset, "charset"), new FileOutputStream(file));
399 }
400
401 /** Check to make sure that the stream has not been closed */
402 private void ensureOpen() throws IOException {
403 if (out == null)
404 throw new IOException("Stream closed");
405 }
406
407 /**
408 * Flushes the stream. This is done by writing any buffered output bytes to
409 * the underlying output stream and then flushing that stream.
410 *
411 * @see java.io.OutputStream#flush()
412 */
413 public void flush() {
414 synchronized (this) {
415 try {
416 ensureOpen();
417 out.flush();
418 }
|