View Javadoc
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
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  import java.nio.charset.UnsupportedCharsetException;
33  
34  /**
35   * A <code>PrintStream</code> 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</code> never throws an
39   * <code>IOException</code>; instead, exceptional situations merely set an
40   * internal flag that can be tested via the <code>checkError</code> method.
41   * Optionally, a <code>PrintStream</code> can be created so as to flush
42   * automatically; this means that the <code>flush</code> method is
43   * automatically invoked after a byte array is written, one of the
44   * <code>println</code> methods is invoked, or a newline character or byte
45   * (<code>'\n'</code>) is written.
46   *
47   * <p> All characters printed by a <code>PrintStream</code> are converted into
48   * bytes using the platform's default character encoding.  The <code>{@link
49   * PrintWriter}</code> class should be used in situations that require writing
50   * characters rather than bytes.
51   *
52   * @author     Frank Yellin
53   * @author     Mark Reinhold
54   * @since      JDK1.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  
72      /**
73       * requireNonNull is explicitly declared here so as not to create an extra
74       * dependency on java.util.Objects.requireNonNull. PrintStream is loaded
75       * early during system initialization.
76       */
77      private static <T> T requireNonNull(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          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
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, requireNonNull(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(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
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      * @since  1.5
206      */
207     public PrintStream(String fileName) throws FileNotFoundException {
208         this(false, new FileOutputStream(fileName));
209     }
210 
211     /**
212      * Creates a new print stream, without automatic line flushing, with the
213      * specified file name and charset.  This convenience constructor creates
214      * the necessary intermediate {@link java.io.OutputStreamWriter
215      * OutputStreamWriter}, which will encode characters using the provided
216      * charset.
217      *
218      * @param  fileName
219      *         The name of the file to use as the destination of this print
220      *         stream.  If the file exists, then it will be truncated to
221      *         zero size; otherwise, a new file will be created.  The output
222      *         will be written to the file and is buffered.
223      *
224      * @param  csn
225      *         The name of a supported {@linkplain java.nio.charset.Charset
226      *         charset}
227      *
228      * @throws  FileNotFoundException
229      *          If the given file object does not denote an existing, writable
230      *          regular file and a new regular file of that name cannot be
231      *          created, or if some other error occurs while opening or
232      *          creating the file
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
273      *          SecurityManager#checkWrite checkWrite(file.getPath())}
274      *          denies write access to the file
275      *
276      * @since  1.5
277      */
278     public PrintStream(File file) throws FileNotFoundException {
279         this(false, new FileOutputStream(file));
280     }
281 
282     /**
283      * Creates a new print stream, without automatic line flushing, with the
284      * specified file and charset.  This convenience constructor creates
285      * the necessary intermediate {@link java.io.OutputStreamWriter
286      * OutputStreamWriter}, which will encode characters using the provided
287      * charset.
288      *
289      * @param  file
290      *         The file to use as the destination of this print stream.  If the
291      *         file exists, then it will be truncated to zero size; otherwise,
292      *         a new file will be created.  The output will be written to the
293      *         file and is buffered.
294      *
295      * @param  csn
296      *         The name of a supported {@linkplain java.nio.charset.Charset
297      *         charset}
298      *
299      * @throws  FileNotFoundException
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             }
340             catch (IOException x) {
341                 trouble = true;
342             }
343         }
344     }
345 
346     private boolean closing = false; /* To avoid recursive closing */
347 
348     /**
349      * Closes the stream.  This is done by flushing the stream and then closing
350      * the underlying output stream.
351      *
352      * @see        java.io.OutputStream#close()
353      */
354     public void close() {
355         synchronized (this) {
356             if (! closing) {
357                 closing = true;
358                 try {
359                     textOut.close();
360                     out.close();
361                 }
362                 catch (IOException x) {
363                     trouble = true;
364                 }
365                 textOut = null;
366                 charOut = null;
367                 out = null;
368             }
369         }
370     }
371 
372     /**
373      * Flushes the stream and checks its error state. The internal error state
374      * is set to <code>true</code> when the underlying output stream throws an
375      * <code>IOException</code> other than <code>InterruptedIOException</code>,
376      * and when the <code>setError</code> method is invoked.  If an operation
377      * on the underlying output stream throws an
378      * <code>InterruptedIOException</code>, then the <code>PrintStream</code>
379      * converts the exception back into an interrupt by doing:
380      * <pre>
381      *     Thread.currentThread().interrupt();
382      * </pre>
383      * or the equivalent.
384      *
385      * @return <code>true</code> if and only if this stream has encountered an
386      *         <code>IOException</code> other than
387      *         <code>InterruptedIOException</code>, or the
388      *         <code>setError</code> method has been invoked
389      */
390     public boolean checkError() {
391         if (out != null)
392             flush();
393         if (out instanceof java.io.PrintStream) {
394             PrintStream ps = (PrintStream) out;
395             return ps.checkError();
396         }
397         return trouble;
398     }
399 
400     /**
401      * Sets the error state of the stream to <code>true</code>.
402      *
403      * <p> This method will cause subsequent invocations of {@link
404      * #checkError()} to return <tt>true</tt> until {@link
405      * #clearError()} is invoked.
406      *
407      * @since JDK1.1
408      */
409     protected void setError() {
410         trouble = true;
411     }
412 
413     /**
414      * Clears the internal error state of this stream.
415      *
416      * <p> This method will cause subsequent invocations of {@link
417      * #checkError()} to return <tt>false</tt> until another write
418      * operation fails and invokes {@link #setError()}.
419      *
420      * @since 1.6
421      */
422     protected void clearError() {
423         trouble = false;
424     }
425 
426     /*
427      * Exception-catching, synchronized output operations,
428      * which also implement the write() methods of OutputStream
429      */
430 
431     /**
432      * Writes the specified byte to this stream.  If the byte is a newline and
433      * automatic flushing is enabled then the <code>flush</code> method will be
434      * invoked.
435      *
436      * <p> Note that the byte is written as given; to write a character that
437      * will be translated according to the platform's default character
438      * encoding, use the <code>print(char)</code> or <code>println(char)</code>
439      * methods.
440      *
441      * @param  b  The byte to be written
442      * @see #print(char)
443      * @see #println(char)
444      */
445     public void write(int b) {
446         try {
447             synchronized (this) {
448                 ensureOpen();
449                 out.write(b);
450                 if ((b == '\n') && autoFlush)
451                     out.flush();
452             }
453         }
454         catch (InterruptedIOException x) {
455             Thread.currentThread().interrupt();
456         }
457         catch (IOException x) {
458             trouble = true;
459         }
460     }
461 
462     /**
463      * Writes <code>len</code> bytes from the specified byte array starting at
464      * offset <code>off</code> to this stream.  If automatic flushing is
465      * enabled then the <code>flush</code> method will be invoked.
466      *
467      * <p> Note that the bytes will be written as given; to write characters
468      * that will be translated according to the platform's default character
469      * encoding, use the <code>print(char)</code> or <code>println(char)</code>
470      * methods.
471      *
472      * @param  buf   A byte array
473      * @param  off   Offset from which to start taking bytes
474      * @param  len   Number of bytes to write
475      */
476     public void write(byte buf[], int off, int len) {
477         try {
478             synchronized (this) {
479                 ensureOpen();
480                 out.write(buf, off, len);
481                 if (autoFlush)
482                     out.flush();
483             }
484         }
485         catch (InterruptedIOException x) {
486             Thread.currentThread().interrupt();
487         }
488         catch (IOException x) {
489             trouble = true;
490         }
491     }
492 
493     /*
494      * The following private methods on the text- and character-output streams
495      * always flush the stream buffers, so that writes to the underlying byte
496      * stream occur as promptly as with the original PrintStream.
497      */
498 
499     private void write(char buf[]) {
500         try {
501             synchronized (this) {
502                 ensureOpen();
503                 textOut.write(buf);
504                 textOut.flushBuffer();
505                 charOut.flushBuffer();
506                 if (autoFlush) {
507                     for (int i = 0; i < buf.length; i++)
508                         if (buf[i] == '\n')
509                             out.flush();
510                 }
511             }
512         }
513         catch (InterruptedIOException x) {
514             Thread.currentThread().interrupt();
515         }
516         catch (IOException x) {
517             trouble = true;
518         }
519     }
520 
521     private void write(String s) {
522         try {
523             synchronized (this) {
524                 ensureOpen();
525                 textOut.write(s);
526                 textOut.flushBuffer();
527                 charOut.flushBuffer();
528                 if (autoFlush && (s.indexOf('\n') >= 0))
529                     out.flush();
530             }
531         }
532         catch (InterruptedIOException x) {
533             Thread.currentThread().interrupt();
534         }
535         catch (IOException x) {
536             trouble = true;
537         }
538     }
539 
540     private void newLine() {
541         try {
542             synchronized (this) {
543                 ensureOpen();
544                 textOut.newLine();
545                 textOut.flushBuffer();
546                 charOut.flushBuffer();
547                 if (autoFlush)
548                     out.flush();
549             }
550         }
551         catch (InterruptedIOException x) {
552             Thread.currentThread().interrupt();
553         }
554         catch (IOException x) {
555             trouble = true;
556         }
557     }
558 
559     /* Methods that do not terminate lines */
560 
561     /**
562      * Prints a boolean value.  The string produced by <code>{@link
563      * java.lang.String#valueOf(boolean)}</code> is translated into bytes
564      * according to the platform's default character encoding, and these bytes
565      * are written in exactly the manner of the
566      * <code>{@link #write(int)}</code> method.
567      *
568      * @param      b   The <code>boolean</code> to be printed
569      */
570     public void print(boolean b) {
571         write(b ? "true" : "false");
572     }
573 
574     /**
575      * Prints a character.  The character is translated into one or more bytes
576      * according to the platform's default character encoding, and these bytes
577      * are written in exactly the manner of the
578      * <code>{@link #write(int)}</code> method.
579      *
580      * @param      c   The <code>char</code> to be printed
581      */
582     public void print(char c) {
583         write(String.valueOf(c));
584     }
585 
586     /**
587      * Prints an integer.  The string produced by <code>{@link
588      * java.lang.String#valueOf(int)}</code> is translated into bytes
589      * according to the platform's default character encoding, and these bytes
590      * are written in exactly the manner of the
591      * <code>{@link #write(int)}</code> method.
592      *
593      * @param      i   The <code>int</code> to be printed
594      * @see        java.lang.Integer#toString(int)
595      */
596     public void print(int i) {
597         write(String.valueOf(i));
598     }
599 
600     /**
601      * Prints a long integer.  The string produced by <code>{@link
602      * java.lang.String#valueOf(long)}</code> is translated into bytes
603      * according to the platform's default character encoding, and these bytes
604      * are written in exactly the manner of the
605      * <code>{@link #write(int)}</code> method.
606      *
607      * @param      l   The <code>long</code> to be printed
608      * @see        java.lang.Long#toString(long)
609      */
610     public void print(long l) {
611         write(String.valueOf(l));
612     }
613 
614     /**
615      * Prints a floating-point number.  The string produced by <code>{@link
616      * java.lang.String#valueOf(float)}</code> is translated into bytes
617      * according to the platform's default character encoding, and these bytes
618      * are written in exactly the manner of the
619      * <code>{@link #write(int)}</code> method.
620      *
621      * @param      f   The <code>float</code> to be printed
622      * @see        java.lang.Float#toString(float)
623      */
624     public void print(float f) {
625         write(String.valueOf(f));
626     }
627 
628     /**
629      * Prints a double-precision floating-point number.  The string produced by
630      * <code>{@link java.lang.String#valueOf(double)}</code> is translated into
631      * bytes according to the platform's default character encoding, and these
632      * bytes are written in exactly the manner of the <code>{@link
633      * #write(int)}</code> method.
634      *
635      * @param      d   The <code>double</code> to be printed
636      * @see        java.lang.Double#toString(double)
637      */
638     public void print(double d) {
639         write(String.valueOf(d));
640     }
641 
642     /**
643      * Prints an array of characters.  The characters are converted into bytes
644      * according to the platform's default character encoding, and these bytes
645      * are written in exactly the manner of the
646      * <code>{@link #write(int)}</code> method.
647      *
648      * @param      s   The array of chars to be printed
649      *
650      * @throws  NullPointerException  If <code>s</code> is <code>null</code>
651      */
652     public void print(char s[]) {
653         write(s);
654     }
655 
656     /**
657      * Prints a string.  If the argument is <code>null</code> then the string
658      * <code>"null"</code> is printed.  Otherwise, the string's characters are
659      * converted into bytes according to the platform's default character
660      * encoding, and these bytes are written in exactly the manner of the
661      * <code>{@link #write(int)}</code> method.
662      *
663      * @param      s   The <code>String</code> to be printed
664      */
665     public void print(String s) {
666         if (s == null) {
667             s = "null";
668         }
669         write(s);
670     }
671 
672     /**
673      * Prints an object.  The string produced by the <code>{@link
674      * java.lang.String#valueOf(Object)}</code> method is translated into bytes
675      * according to the platform's default character encoding, and these bytes
676      * are written in exactly the manner of the
677      * <code>{@link #write(int)}</code> method.
678      *
679      * @param      obj   The <code>Object</code> to be printed
680      * @see        java.lang.Object#toString()
681      */
682     public void print(Object obj) {
683         write(String.valueOf(obj));
684     }
685 
686 
687     /* Methods that do terminate lines */
688 
689     /**
690      * Terminates the current line by writing the line separator string.  The
691      * line separator string is defined by the system property
692      * <code>line.separator</code>, and is not necessarily a single newline
693      * character (<code>'\n'</code>).
694      */
695     public void println() {
696         newLine();
697     }
698 
699     /**
700      * Prints a boolean and then terminate the line.  This method behaves as
701      * though it invokes <code>{@link #print(boolean)}</code> and then
702      * <code>{@link #println()}</code>.
703      *
704      * @param x  The <code>boolean</code> to be printed
705      */
706     public void println(boolean x) {
707         synchronized (this) {
708             print(x);
709             newLine();
710         }
711     }
712 
713     /**
714      * Prints a character and then terminate the line.  This method behaves as
715      * though it invokes <code>{@link #print(char)}</code> and then
716      * <code>{@link #println()}</code>.
717      *
718      * @param x  The <code>char</code> to be printed.
719      */
720     public void println(char x) {
721         synchronized (this) {
722             print(x);
723             newLine();
724         }
725     }
726 
727     /**
728      * Prints an integer and then terminate the line.  This method behaves as
729      * though it invokes <code>{@link #print(int)}</code> and then
730      * <code>{@link #println()}</code>.
731      *
732      * @param x  The <code>int</code> to be printed.
733      */
734     public void println(int x) {
735         synchronized (this) {
736             print(x);
737             newLine();
738         }
739     }
740 
741     /**
742      * Prints a long and then terminate the line.  This method behaves as
743      * though it invokes <code>{@link #print(long)}</code> and then
744      * <code>{@link #println()}</code>.
745      *
746      * @param x  a The <code>long</code> to be printed.
747      */
748     public void println(long x) {
749         synchronized (this) {
750             print(x);
751             newLine();
752         }
753     }
754 
755     /**
756      * Prints a float and then terminate the line.  This method behaves as
757      * though it invokes <code>{@link #print(float)}</code> and then
758      * <code>{@link #println()}</code>.
759      *
760      * @param x  The <code>float</code> to be printed.
761      */
762     public void println(float x) {
763         synchronized (this) {
764             print(x);
765             newLine();
766         }
767     }
768 
769     /**
770      * Prints a double and then terminate the line.  This method behaves as
771      * though it invokes <code>{@link #print(double)}</code> and then
772      * <code>{@link #println()}</code>.
773      *
774      * @param x  The <code>double</code> to be printed.
775      */
776     public void println(double x) {
777         synchronized (this) {
778             print(x);
779             newLine();
780         }
781     }
782 
783     /**
784      * Prints an array of characters and then terminate the line.  This method
785      * behaves as though it invokes <code>{@link #print(char[])}</code> and
786      * then <code>{@link #println()}</code>.
787      *
788      * @param x  an array of chars to print.
789      */
790     public void println(char x[]) {
791         synchronized (this) {
792             print(x);
793             newLine();
794         }
795     }
796 
797     /**
798      * Prints a String and then terminate the line.  This method behaves as
799      * though it invokes <code>{@link #print(String)}</code> and then
800      * <code>{@link #println()}</code>.
801      *
802      * @param x  The <code>String</code> to be printed.
803      */
804     public void println(String x) {
805         synchronized (this) {
806             print(x);
807             newLine();
808         }
809     }
810 
811     /**
812      * Prints an Object and then terminate the line.  This method calls
813      * at first String.valueOf(x) to get the printed object's string value,
814      * then behaves as
815      * though it invokes <code>{@link #print(String)}</code> and then
816      * <code>{@link #println()}</code>.
817      *
818      * @param x  The <code>Object</code> to be printed.
819      */
820     public void println(Object x) {
821         String s = String.valueOf(x);
822         synchronized (this) {
823             print(s);
824             newLine();
825         }
826     }
827 
828 
829     /**
830      * A convenience method to write a formatted string to this output stream
831      * using the specified format string and arguments.
832      *
833      * <p> An invocation of this method of the form <tt>out.printf(format,
834      * args)</tt> behaves in exactly the same way as the invocation
835      *
836      * <pre>
837      *     out.format(format, args) </pre>
838      *
839      * @param  format
840      *         A format string as described in <a
841      *         href="../util/Formatter.html#syntax">Format string syntax</a>
842      *
843      * @param  args
844      *         Arguments referenced by the format specifiers in the format
845      *         string.  If there are more arguments than format specifiers, the
846      *         extra arguments are ignored.  The number of arguments is
847      *         variable and may be zero.  The maximum number of arguments is
848      *         limited by the maximum dimension of a Java array as defined by
849      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
850      *         The behaviour on a
851      *         <tt>null</tt> argument depends on the <a
852      *         href="../util/Formatter.html#syntax">conversion</a>.
853      *
854      * @throws  java.util.IllegalFormatException
855      *          If a format string contains an illegal syntax, a format
856      *          specifier that is incompatible with the given arguments,
857      *          insufficient arguments given the format string, or other
858      *          illegal conditions.  For specification of all possible
859      *          formatting errors, see the <a
860      *          href="../util/Formatter.html#detail">Details</a> section of the
861      *          formatter class specification.
862      *
863      * @throws  NullPointerException
864      *          If the <tt>format</tt> is <tt>null</tt>
865      *
866      * @return  This output stream
867      *
868      * @since  1.5
869      */
870     public PrintStream printf(String format, Object ... args) {
871         return format(format, args);
872     }
873 
874     /**
875      * A convenience method to write a formatted string to this output stream
876      * using the specified format string and arguments.
877      *
878      * <p> An invocation of this method of the form <tt>out.printf(l, format,
879      * args)</tt> behaves in exactly the same way as the invocation
880      *
881      * <pre>
882      *     out.format(l, format, args) </pre>
883      *
884      * @param  l
885      *         The {@linkplain java.util.Locale locale} to apply during
886      *         formatting.  If <tt>l</tt> is <tt>null</tt> then no localization
887      *         is applied.
888      *
889      * @param  format
890      *         A format string as described in <a
891      *         href="../util/Formatter.html#syntax">Format string syntax</a>
892      *
893      * @param  args
894      *         Arguments referenced by the format specifiers in the format
895      *         string.  If there are more arguments than format specifiers, the
896      *         extra arguments are ignored.  The number of arguments is
897      *         variable and may be zero.  The maximum number of arguments is
898      *         limited by the maximum dimension of a Java array as defined by
899      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
900      *         The behaviour on a
901      *         <tt>null</tt> argument depends on the <a
902      *         href="../util/Formatter.html#syntax">conversion</a>.
903      *
904      * @throws  java.util.IllegalFormatException
905      *          If a format string contains an illegal syntax, a format
906      *          specifier that is incompatible with the given arguments,
907      *          insufficient arguments given the format string, or other
908      *          illegal conditions.  For specification of all possible
909      *          formatting errors, see the <a
910      *          href="../util/Formatter.html#detail">Details</a> section of the
911      *          formatter class specification.
912      *
913      * @throws  NullPointerException
914      *          If the <tt>format</tt> is <tt>null</tt>
915      *
916      * @return  This output stream
917      *
918      * @since  1.5
919      */
920     public PrintStream printf(Locale l, String format, Object ... args) {
921         return format(l, format, args);
922     }
923 
924     /**
925      * Writes a formatted string to this output stream using the specified
926      * format string and arguments.
927      *
928      * <p> The locale always used is the one returned by {@link
929      * java.util.Locale#getDefault() Locale.getDefault()}, regardless of any
930      * previous invocations of other formatting methods on this object.
931      *
932      * @param  format
933      *         A format string as described in <a
934      *         href="../util/Formatter.html#syntax">Format string syntax</a>
935      *
936      * @param  args
937      *         Arguments referenced by the format specifiers in the format
938      *         string.  If there are more arguments than format specifiers, the
939      *         extra arguments are ignored.  The number of arguments is
940      *         variable and may be zero.  The maximum number of arguments is
941      *         limited by the maximum dimension of a Java array as defined by
942      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
943      *         The behaviour on a
944      *         <tt>null</tt> argument depends on the <a
945      *         href="../util/Formatter.html#syntax">conversion</a>.
946      *
947      * @throws  java.util.IllegalFormatException
948      *          If a format string contains an illegal syntax, a format
949      *          specifier that is incompatible with the given arguments,
950      *          insufficient arguments given the format string, or other
951      *          illegal conditions.  For specification of all possible
952      *          formatting errors, see the <a
953      *          href="../util/Formatter.html#detail">Details</a> section of the
954      *          formatter class specification.
955      *
956      * @throws  NullPointerException
957      *          If the <tt>format</tt> is <tt>null</tt>
958      *
959      * @return  This output stream
960      *
961      * @since  1.5
962      */
963     public PrintStream format(String format, Object ... args) {
964         try {
965             synchronized (this) {
966                 ensureOpen();
967                 if ((formatter == null)
968                     || (formatter.locale() != Locale.getDefault()))
969                     formatter = new Formatter((Appendable) this);
970                 formatter.format(Locale.getDefault(), format, args);
971             }
972         } catch (InterruptedIOException x) {
973             Thread.currentThread().interrupt();
974         } catch (IOException x) {
975             trouble = true;
976         }
977         return this;
978     }
979 
980     /**
981      * Writes a formatted string to this output stream using the specified
982      * format string and arguments.
983      *
984      * @param  l
985      *         The {@linkplain java.util.Locale locale} to apply during
986      *         formatting.  If <tt>l</tt> is <tt>null</tt> then no localization
987      *         is applied.
988      *
989      * @param  format
990      *         A format string as described in <a
991      *         href="../util/Formatter.html#syntax">Format string syntax</a>
992      *
993      * @param  args
994      *         Arguments referenced by the format specifiers in the format
995      *         string.  If there are more arguments than format specifiers, the
996      *         extra arguments are ignored.  The number of arguments is
997      *         variable and may be zero.  The maximum number of arguments is
998      *         limited by the maximum dimension of a Java array as defined by
999      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
1000      *         The behaviour on a
1001      *         <tt>null</tt> argument depends on the <a
1002      *         href="../util/Formatter.html#syntax">conversion</a>.
1003      *
1004      * @throws  java.util.IllegalFormatException
1005      *          If a format string contains an illegal syntax, a format
1006      *          specifier that is incompatible with the given arguments,
1007      *          insufficient arguments given the format string, or other
1008      *          illegal conditions.  For specification of all possible
1009      *          formatting errors, see the <a
1010      *          href="../util/Formatter.html#detail">Details</a> section of the
1011      *          formatter class specification.
1012      *
1013      * @throws  NullPointerException
1014      *          If the <tt>format</tt> is <tt>null</tt>
1015      *
1016      * @return  This output stream
1017      *
1018      * @since  1.5
1019      */
1020     public PrintStream format(Locale l, String format, Object ... args) {
1021         try {
1022             synchronized (this) {
1023                 ensureOpen();
1024                 if ((formatter == null)
1025                     || (formatter.locale() != l))
1026                     formatter = new Formatter(this, l);
1027                 formatter.format(l, format, args);
1028             }
1029         } catch (InterruptedIOException x) {
1030             Thread.currentThread().interrupt();
1031         } catch (IOException x) {
1032             trouble = true;
1033         }
1034         return this;
1035     }
1036 
1037     /**
1038      * Appends the specified character sequence to this output stream.
1039      *
1040      * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
1041      * behaves in exactly the same way as the invocation
1042      *
1043      * <pre>
1044      *     out.print(csq.toString()) </pre>
1045      *
1046      * <p> Depending on the specification of <tt>toString</tt> for the
1047      * character sequence <tt>csq</tt>, the entire sequence may not be
1048      * appended.  For instance, invoking then <tt>toString</tt> method of a
1049      * character buffer will return a subsequence whose content depends upon
1050      * the buffer's position and limit.
1051      *
1052      * @param  csq
1053      *         The character sequence to append.  If <tt>csq</tt> is
1054      *         <tt>null</tt>, then the four characters <tt>"null"</tt> are
1055      *         appended to this output stream.
1056      *
1057      * @return  This output stream
1058      *
1059      * @since  1.5
1060      */
1061     public PrintStream append(CharSequence csq) {
1062         if (csq == null)
1063             print("null");
1064         else
1065             print(csq.toString());
1066         return this;
1067     }
1068 
1069     /**
1070      * Appends a subsequence of the specified character sequence to this output
1071      * stream.
1072      *
1073      * <p> An invocation of this method of the form <tt>out.append(csq, start,
1074      * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
1075      * exactly the same way as the invocation
1076      *
1077      * <pre>
1078      *     out.print(csq.subSequence(start, end).toString()) </pre>
1079      *
1080      * @param  csq
1081      *         The character sequence from which a subsequence will be
1082      *         appended.  If <tt>csq</tt> is <tt>null</tt>, then characters
1083      *         will be appended as if <tt>csq</tt> contained the four
1084      *         characters <tt>"null"</tt>.
1085      *
1086      * @param  start
1087      *         The index of the first character in the subsequence
1088      *
1089      * @param  end
1090      *         The index of the character following the last character in the
1091      *         subsequence
1092      *
1093      * @return  This output stream
1094      *
1095      * @throws  IndexOutOfBoundsException
1096      *          If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
1097      *          is greater than <tt>end</tt>, or <tt>end</tt> is greater than
1098      *          <tt>csq.length()</tt>
1099      *
1100      * @since  1.5
1101      */
1102     public PrintStream append(CharSequence csq, int start, int end) {
1103         CharSequence cs = (csq == null ? "null" : csq);
1104         write(cs.subSequence(start, end).toString());
1105         return this;
1106     }
1107 
1108     /**
1109      * Appends the specified character to this output stream.
1110      *
1111      * <p> An invocation of this method of the form <tt>out.append(c)</tt>
1112      * behaves in exactly the same way as the invocation
1113      *
1114      * <pre>
1115      *     out.print(c) </pre>
1116      *
1117      * @param  c
1118      *         The 16-bit character to append
1119      *
1120      * @return  This output stream
1121      *
1122      * @since  1.5
1123      */
1124     public PrintStream append(char c) {
1125         print(c);
1126         return this;
1127     }
1128 
1129 }