1 /* |
1 /* |
2 * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
25 |
25 |
26 package java.io; |
26 package java.io; |
27 |
27 |
28 import java.util.Formatter; |
28 import java.util.Formatter; |
29 import java.util.Locale; |
29 import java.util.Locale; |
30 |
30 import java.nio.charset.Charset; |
|
31 import java.nio.charset.IllegalCharsetNameException; |
|
32 import java.nio.charset.UnsupportedCharsetException; |
31 |
33 |
32 /** |
34 /** |
33 * A <code>PrintStream</code> adds functionality to another output stream, |
35 * A <code>PrintStream</code> adds functionality to another output stream, |
34 * namely the ability to print representations of various data values |
36 * namely the ability to print representations of various data values |
35 * conveniently. Two other features are provided as well. Unlike other output |
37 * conveniently. Two other features are provided as well. Unlike other output |
54 |
56 |
55 public class PrintStream extends FilterOutputStream |
57 public class PrintStream extends FilterOutputStream |
56 implements Appendable, Closeable |
58 implements Appendable, Closeable |
57 { |
59 { |
58 |
60 |
59 private boolean autoFlush = false; |
61 private final boolean autoFlush; |
60 private boolean trouble = false; |
62 private boolean trouble = false; |
61 private Formatter formatter; |
63 private Formatter formatter; |
62 |
64 |
63 /** |
65 /** |
64 * Track both the text- and character-output streams, so that their buffers |
66 * Track both the text- and character-output streams, so that their buffers |
66 */ |
68 */ |
67 private BufferedWriter textOut; |
69 private BufferedWriter textOut; |
68 private OutputStreamWriter charOut; |
70 private OutputStreamWriter charOut; |
69 |
71 |
70 /** |
72 /** |
|
73 * nonNull is explicitly delcared here so as not to create an extra |
|
74 * dependency on java.util.Objects.nonNull. PrintStream is loaded |
|
75 * early during system initialization. |
|
76 */ |
|
77 private static <T> T nonNull(T obj, String message) { |
|
78 if (obj == null) |
|
79 throw new NullPointerException(message); |
|
80 return obj; |
|
81 } |
|
82 |
|
83 /** |
|
84 * Returns a charset object for the given charset name. |
|
85 * @throws NullPointerException is csn is null |
|
86 * @throws UnsupportedEncodingException if the charset is not supported |
|
87 */ |
|
88 private static Charset toCharset(String csn) |
|
89 throws UnsupportedEncodingException |
|
90 { |
|
91 nonNull(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 /** |
71 * Creates a new print stream. This stream will not flush automatically. |
127 * Creates a new print stream. This stream will not flush automatically. |
72 * |
128 * |
73 * @param out The output stream to which values and objects will be |
129 * @param out The output stream to which values and objects will be |
74 * printed |
130 * printed |
75 * |
131 * |
76 * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream) |
132 * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream) |
77 */ |
133 */ |
78 public PrintStream(OutputStream out) { |
134 public PrintStream(OutputStream out) { |
79 this(out, false); |
135 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 } |
136 } |
102 |
137 |
103 /** |
138 /** |
104 * Creates a new print stream. |
139 * Creates a new print stream. |
105 * |
140 * |
111 * character or byte (<code>'\n'</code>) is written |
146 * character or byte (<code>'\n'</code>) is written |
112 * |
147 * |
113 * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean) |
148 * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean) |
114 */ |
149 */ |
115 public PrintStream(OutputStream out, boolean autoFlush) { |
150 public PrintStream(OutputStream out, boolean autoFlush) { |
116 this(autoFlush, out); |
151 this(autoFlush, nonNull(out, "Null output stream")); |
117 init(new OutputStreamWriter(this)); |
|
118 } |
152 } |
119 |
153 |
120 /** |
154 /** |
121 * Creates a new print stream. |
155 * Creates a new print stream. |
122 * |
156 * |
136 * @since 1.4 |
170 * @since 1.4 |
137 */ |
171 */ |
138 public PrintStream(OutputStream out, boolean autoFlush, String encoding) |
172 public PrintStream(OutputStream out, boolean autoFlush, String encoding) |
139 throws UnsupportedEncodingException |
173 throws UnsupportedEncodingException |
140 { |
174 { |
141 this(autoFlush, out); |
175 this(autoFlush, |
142 init(new OutputStreamWriter(this, encoding)); |
176 nonNull(out, "Null output stream"), |
|
177 toCharset(encoding)); |
143 } |
178 } |
144 |
179 |
145 /** |
180 /** |
146 * Creates a new print stream, without automatic line flushing, with the |
181 * Creates a new print stream, without automatic line flushing, with the |
147 * specified file name. This convenience constructor creates |
182 * specified file name. This convenience constructor creates |
208 * @since 1.5 |
242 * @since 1.5 |
209 */ |
243 */ |
210 public PrintStream(String fileName, String csn) |
244 public PrintStream(String fileName, String csn) |
211 throws FileNotFoundException, UnsupportedEncodingException |
245 throws FileNotFoundException, UnsupportedEncodingException |
212 { |
246 { |
213 this(false, new FileOutputStream(fileName)); |
247 // ensure charset is checked before the file is opened |
214 init(new OutputStreamWriter(this, csn)); |
248 this(false, toCharset(csn), new FileOutputStream(fileName)); |
215 } |
249 } |
216 |
250 |
217 /** |
251 /** |
218 * Creates a new print stream, without automatic line flushing, with the |
252 * Creates a new print stream, without automatic line flushing, with the |
219 * specified file. This convenience constructor creates the necessary |
253 * specified file. This convenience constructor creates the necessary |
280 * @since 1.5 |
313 * @since 1.5 |
281 */ |
314 */ |
282 public PrintStream(File file, String csn) |
315 public PrintStream(File file, String csn) |
283 throws FileNotFoundException, UnsupportedEncodingException |
316 throws FileNotFoundException, UnsupportedEncodingException |
284 { |
317 { |
285 this(false, new FileOutputStream(file)); |
318 // ensure charset is checked before the file is opened |
286 init(new OutputStreamWriter(this, csn)); |
319 this(false, toCharset(csn), new FileOutputStream(file)); |
287 } |
320 } |
288 |
321 |
289 /** Check to make sure that the stream has not been closed */ |
322 /** Check to make sure that the stream has not been closed */ |
290 private void ensureOpen() throws IOException { |
323 private void ensureOpen() throws IOException { |
291 if (out == null) |
324 if (out == null) |