Home | History | Annotate | Download | only in io
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
      4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      5  *
      6  * This code is free software; you can redistribute it and/or modify it
      7  * under the terms of the GNU General Public License version 2 only, as
      8  * published by the Free Software Foundation.  Oracle designates this
      9  * particular file as subject to the "Classpath" exception as provided
     10  * by Oracle in the LICENSE file that accompanied this code.
     11  *
     12  * This code is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  * version 2 for more details (a copy is included in the LICENSE file that
     16  * accompanied this code).
     17  *
     18  * You should have received a copy of the GNU General Public License version
     19  * 2 along with this work; if not, write to the Free Software Foundation,
     20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     21  *
     22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     23  * or visit www.oracle.com if you need additional information or have any
     24  * questions.
     25  */
     26 
     27 package java.io;
     28 
     29 import java.util.Formatter;
     30 import java.util.Locale;
     31 import java.nio.charset.Charset;
     32 import java.nio.charset.IllegalCharsetNameException;
     33 import java.nio.charset.UnsupportedCharsetException;
     34 
     35 /**
     36  * A <code>PrintStream</code> adds functionality to another output stream,
     37  * namely the ability to print representations of various data values
     38  * conveniently.  Two other features are provided as well.  Unlike other output
     39  * streams, a <code>PrintStream</code> never throws an
     40  * <code>IOException</code>; instead, exceptional situations merely set an
     41  * internal flag that can be tested via the <code>checkError</code> method.
     42  * Optionally, a <code>PrintStream</code> can be created so as to flush
     43  * automatically; this means that the <code>flush</code> method is
     44  * automatically invoked after a byte array is written, one of the
     45  * <code>println</code> methods is invoked, or a newline character or byte
     46  * (<code>'\n'</code>) is written.
     47  *
     48  * <p> All characters printed by a <code>PrintStream</code> are converted into
     49  * bytes using the platform's default character encoding.  The <code>{@link
     50  * PrintWriter}</code> class should be used in situations that require writing
     51  * characters rather than bytes.
     52  *
     53  * @author     Frank Yellin
     54  * @author     Mark Reinhold
     55  * @since      JDK1.0
     56  */
     57 
     58 public class PrintStream extends FilterOutputStream
     59     implements Appendable, Closeable
     60 {
     61 
     62     private final boolean autoFlush;
     63     private boolean trouble = false;
     64     private Formatter formatter;
     65 
     66     /**
     67      * Track both the text- and character-output streams, so that their buffers
     68      * can be flushed without flushing the entire stream.
     69      */
     70     private BufferedWriter textOut;
     71     private OutputStreamWriter charOut;
     72 
     73     // Android-added: Lazy initialization of charOut and textOut.
     74     private Charset charset;
     75 
     76     /**
     77      * requireNonNull is explicitly declared here so as not to create an extra
     78      * dependency on java.util.Objects.requireNonNull. PrintStream is loaded
     79      * early during system initialization.
     80      */
     81     private static <T> T requireNonNull(T obj, String message) {
     82         if (obj == null)
     83             throw new NullPointerException(message);
     84         return obj;
     85     }
     86 
     87     /**
     88      * Returns a charset object for the given charset name.
     89      * @throws NullPointerException          is csn is null
     90      * @throws UnsupportedEncodingException  if the charset is not supported
     91      */
     92     private static Charset toCharset(String csn)
     93         throws UnsupportedEncodingException
     94     {
     95         requireNonNull(csn, "charsetName");
     96         try {
     97             return Charset.forName(csn);
     98         } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
     99             // UnsupportedEncodingException should be thrown
    100             throw new UnsupportedEncodingException(csn);
    101         }
    102     }
    103 
    104     /* Private constructors */
    105     private PrintStream(boolean autoFlush, OutputStream out) {
    106         super(out);
    107         this.autoFlush = autoFlush;
    108         // Android-changed: Lazy initialization of charOut and textOut.
    109         // this.charOut = new OutputStreamWriter(this);
    110         // this.textOut = new BufferedWriter(charOut);
    111     }
    112 
    113     private PrintStream(boolean autoFlush, OutputStream out, Charset charset) {
    114         super(out);
    115         this.autoFlush = autoFlush;
    116         // Android-changed: Lazy initialization of charOut and textOut.
    117         // this.charOut = new OutputStreamWriter(this, charset);
    118         // this.textOut = new BufferedWriter(charOut);
    119         this.charset = charset;
    120     }
    121 
    122     /* Variant of the private constructor so that the given charset name
    123      * can be verified before evaluating the OutputStream argument. Used
    124      * by constructors creating a FileOutputStream that also take a
    125      * charset name.
    126      */
    127     private PrintStream(boolean autoFlush, Charset charset, OutputStream out)
    128         throws UnsupportedEncodingException
    129     {
    130         this(autoFlush, out, charset);
    131     }
    132 
    133     /**
    134      * Creates a new print stream.  This stream will not flush automatically.
    135      *
    136      * @param  out        The output stream to which values and objects will be
    137      *                    printed
    138      *
    139      * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
    140      */
    141     public PrintStream(OutputStream out) {
    142         this(out, false);
    143     }
    144 
    145     /**
    146      * Creates a new print stream.
    147      *
    148      * @param  out        The output stream to which values and objects will be
    149      *                    printed
    150      * @param  autoFlush  A boolean; if true, the output buffer will be flushed
    151      *                    whenever a byte array is written, one of the
    152      *                    <code>println</code> methods is invoked, or a newline
    153      *                    character or byte (<code>'\n'</code>) is written
    154      *
    155      * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
    156      */
    157     public PrintStream(OutputStream out, boolean autoFlush) {
    158         this(autoFlush, requireNonNull(out, "Null output stream"));
    159     }
    160 
    161     /**
    162      * Creates a new print stream.
    163      *
    164      * @param  out        The output stream to which values and objects will be
    165      *                    printed
    166      * @param  autoFlush  A boolean; if true, the output buffer will be flushed
    167      *                    whenever a byte array is written, one of the
    168      *                    <code>println</code> methods is invoked, or a newline
    169      *                    character or byte (<code>'\n'</code>) is written
    170      * @param  encoding   The name of a supported
    171      *                    <a href="../lang/package-summary.html#charenc">
    172      *                    character encoding</a>
    173      *
    174      * @throws  UnsupportedEncodingException
    175      *          If the named encoding is not supported
    176      *
    177      * @since  1.4
    178      */
    179     public PrintStream(OutputStream out, boolean autoFlush, String encoding)
    180         throws UnsupportedEncodingException
    181     {
    182         this(autoFlush,
    183              requireNonNull(out, "Null output stream"),
    184              toCharset(encoding));
    185     }
    186 
    187     /**
    188      * Creates a new print stream, without automatic line flushing, with the
    189      * specified file name.  This convenience constructor creates
    190      * the necessary intermediate {@link java.io.OutputStreamWriter
    191      * OutputStreamWriter}, which will encode characters using the
    192      * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}
    193      * for this instance of the Java virtual machine.
    194      *
    195      * @param  fileName
    196      *         The name of the file to use as the destination of this print
    197      *         stream.  If the file exists, then it will be truncated to
    198      *         zero size; otherwise, a new file will be created.  The output
    199      *         will be written to the file and is buffered.
    200      *
    201      * @throws  FileNotFoundException
    202      *          If the given file object does not denote an existing, writable
    203      *          regular file and a new regular file of that name cannot be
    204      *          created, or if some other error occurs while opening or
    205      *          creating the file
    206      *
    207      * @throws  SecurityException
    208      *          If a security manager is present and {@link
    209      *          SecurityManager#checkWrite checkWrite(fileName)} denies write
    210      *          access to the file
    211      *
    212      * @since  1.5
    213      */
    214     public PrintStream(String fileName) throws FileNotFoundException {
    215         this(false, new FileOutputStream(fileName));
    216     }
    217 
    218     /**
    219      * Creates a new print stream, without automatic line flushing, with the
    220      * specified file name and charset.  This convenience constructor creates
    221      * the necessary intermediate {@link java.io.OutputStreamWriter
    222      * OutputStreamWriter}, which will encode characters using the provided
    223      * charset.
    224      *
    225      * @param  fileName
    226      *         The name of the file to use as the destination of this print
    227      *         stream.  If the file exists, then it will be truncated to
    228      *         zero size; otherwise, a new file will be created.  The output
    229      *         will be written to the file and is buffered.
    230      *
    231      * @param  csn
    232      *         The name of a supported {@linkplain java.nio.charset.Charset
    233      *         charset}
    234      *
    235      * @throws  FileNotFoundException
    236      *          If the given file object does not denote an existing, writable
    237      *          regular file and a new regular file of that name cannot be
    238      *          created, or if some other error occurs while opening or
    239      *          creating the file
    240      *
    241      * @throws  SecurityException
    242      *          If a security manager is present and {@link
    243      *          SecurityManager#checkWrite checkWrite(fileName)} denies write
    244      *          access to the file
    245      *
    246      * @throws  UnsupportedEncodingException
    247      *          If the named charset is not supported
    248      *
    249      * @since  1.5
    250      */
    251     public PrintStream(String fileName, String csn)
    252         throws FileNotFoundException, UnsupportedEncodingException
    253     {
    254         // ensure charset is checked before the file is opened
    255         this(false, toCharset(csn), new FileOutputStream(fileName));
    256     }
    257 
    258     /**
    259      * Creates a new print stream, without automatic line flushing, with the
    260      * specified file.  This convenience constructor creates the necessary
    261      * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
    262      * which will encode characters using the {@linkplain
    263      * java.nio.charset.Charset#defaultCharset() default charset} for this
    264      * instance of the Java virtual machine.
    265      *
    266      * @param  file
    267      *         The file to use as the destination of this print stream.  If the
    268      *         file exists, then it will be truncated to zero size; otherwise,
    269      *         a new file will be created.  The output will be written to the
    270      *         file and is buffered.
    271      *
    272      * @throws  FileNotFoundException
    273      *          If the given file object does not denote an existing, writable
    274      *          regular file and a new regular file of that name cannot be
    275      *          created, or if some other error occurs while opening or
    276      *          creating the file
    277      *
    278      * @throws  SecurityException
    279      *          If a security manager is present and {@link
    280      *          SecurityManager#checkWrite checkWrite(file.getPath())}
    281      *          denies write access to the file
    282      *
    283      * @since  1.5
    284      */
    285     public PrintStream(File file) throws FileNotFoundException {
    286         this(false, new FileOutputStream(file));
    287     }
    288 
    289     /**
    290      * Creates a new print stream, without automatic line flushing, with the
    291      * specified file and charset.  This convenience constructor creates
    292      * the necessary intermediate {@link java.io.OutputStreamWriter
    293      * OutputStreamWriter}, which will encode characters using the provided
    294      * charset.
    295      *
    296      * @param  file
    297      *         The file to use as the destination of this print stream.  If the
    298      *         file exists, then it will be truncated to zero size; otherwise,
    299      *         a new file will be created.  The output will be written to the
    300      *         file and is buffered.
    301      *
    302      * @param  csn
    303      *         The name of a supported {@linkplain java.nio.charset.Charset
    304      *         charset}
    305      *
    306      * @throws  FileNotFoundException
    307      *          If the given file object does not denote an existing, writable
    308      *          regular file and a new regular file of that name cannot be
    309      *          created, or if some other error occurs while opening or
    310      *          creating the file
    311      *
    312      * @throws  SecurityException
    313      *          If a security manager is present and {@link
    314      *          SecurityManager#checkWrite checkWrite(file.getPath())}
    315      *          denies write access to the file
    316      *
    317      * @throws  UnsupportedEncodingException
    318      *          If the named charset is not supported
    319      *
    320      * @since  1.5
    321      */
    322     public PrintStream(File file, String csn)
    323         throws FileNotFoundException, UnsupportedEncodingException
    324     {
    325         // ensure charset is checked before the file is opened
    326         this(false, toCharset(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             }
    347             catch (IOException x) {
    348                 trouble = true;
    349             }
    350         }
    351     }
    352 
    353     private boolean closing = false; /* To avoid recursive closing */
    354 
    355     // BEGIN Android-added: Lazy initialization of charOut and textOut.
    356     private BufferedWriter getTextOut() {
    357         if (textOut == null) {
    358             charOut = charset != null ? new OutputStreamWriter(this, charset) :
    359                     new OutputStreamWriter(this);
    360             textOut = new BufferedWriter(charOut);
    361         }
    362         return textOut;
    363     }
    364     // END Android-added: Lazy initialization of charOut and textOut.
    365 
    366     /**
    367      * Closes the stream.  This is done by flushing the stream and then closing
    368      * the underlying output stream.
    369      *
    370      * @see        java.io.OutputStream#close()
    371      */
    372     public void close() {
    373         synchronized (this) {
    374             if (! closing) {
    375                 closing = true;
    376                 try {
    377                     // BEGIN Android-changed: Lazy initialization of charOut and textOut.
    378                     // textOut.close();
    379                     if (textOut != null) {
    380                         textOut.close();
    381                     }
    382                     // END Android-changed: Lazy initialization of charOut and textOut.
    383                     out.close();
    384                 }
    385                 catch (IOException x) {
    386                     trouble = true;
    387                 }
    388                 textOut = null;
    389                 charOut = null;
    390                 out = null;
    391             }
    392         }
    393     }
    394 
    395     /**
    396      * Flushes the stream and checks its error state. The internal error state
    397      * is set to <code>true</code> when the underlying output stream throws an
    398      * <code>IOException</code> other than <code>InterruptedIOException</code>,
    399      * and when the <code>setError</code> method is invoked.  If an operation
    400      * on the underlying output stream throws an
    401      * <code>InterruptedIOException</code>, then the <code>PrintStream</code>
    402      * converts the exception back into an interrupt by doing:
    403      * <pre>
    404      *     Thread.currentThread().interrupt();
    405      * </pre>
    406      * or the equivalent.
    407      *
    408      * @return <code>true</code> if and only if this stream has encountered an
    409      *         <code>IOException</code> other than
    410      *         <code>InterruptedIOException</code>, or the
    411      *         <code>setError</code> method has been invoked
    412      */
    413     public boolean checkError() {
    414         if (out != null)
    415             flush();
    416         if (out instanceof java.io.PrintStream) {
    417             PrintStream ps = (PrintStream) out;
    418             return ps.checkError();
    419         }
    420         return trouble;
    421     }
    422 
    423     /**
    424      * Sets the error state of the stream to <code>true</code>.
    425      *
    426      * <p> This method will cause subsequent invocations of {@link
    427      * #checkError()} to return <tt>true</tt> until {@link
    428      * #clearError()} is invoked.
    429      *
    430      * @since JDK1.1
    431      */
    432     protected void setError() {
    433         trouble = true;
    434     }
    435 
    436     /**
    437      * Clears the internal error state of this stream.
    438      *
    439      * <p> This method will cause subsequent invocations of {@link
    440      * #checkError()} to return <tt>false</tt> until another write
    441      * operation fails and invokes {@link #setError()}.
    442      *
    443      * @since 1.6
    444      */
    445     protected void clearError() {
    446         trouble = false;
    447     }
    448 
    449     /*
    450      * Exception-catching, synchronized output operations,
    451      * which also implement the write() methods of OutputStream
    452      */
    453 
    454     /**
    455      * Writes the specified byte to this stream.  If the byte is a newline and
    456      * automatic flushing is enabled then the <code>flush</code> method will be
    457      * invoked.
    458      *
    459      * <p> Note that the byte is written as given; to write a character that
    460      * will be translated according to the platform's default character
    461      * encoding, use the <code>print(char)</code> or <code>println(char)</code>
    462      * methods.
    463      *
    464      * @param  b  The byte to be written
    465      * @see #print(char)
    466      * @see #println(char)
    467      */
    468     public void write(int b) {
    469         try {
    470             synchronized (this) {
    471                 ensureOpen();
    472                 out.write(b);
    473                 if ((b == '\n') && autoFlush)
    474                     out.flush();
    475             }
    476         }
    477         catch (InterruptedIOException x) {
    478             Thread.currentThread().interrupt();
    479         }
    480         catch (IOException x) {
    481             trouble = true;
    482         }
    483     }
    484 
    485     /**
    486      * Writes <code>len</code> bytes from the specified byte array starting at
    487      * offset <code>off</code> to this stream.  If automatic flushing is
    488      * enabled then the <code>flush</code> method will be invoked.
    489      *
    490      * <p> Note that the bytes will be written as given; to write characters
    491      * that will be translated according to the platform's default character
    492      * encoding, use the <code>print(char)</code> or <code>println(char)</code>
    493      * methods.
    494      *
    495      * @param  buf   A byte array
    496      * @param  off   Offset from which to start taking bytes
    497      * @param  len   Number of bytes to write
    498      */
    499     public void write(byte buf[], int off, int len) {
    500         try {
    501             synchronized (this) {
    502                 ensureOpen();
    503                 out.write(buf, off, len);
    504                 if (autoFlush)
    505                     out.flush();
    506             }
    507         }
    508         catch (InterruptedIOException x) {
    509             Thread.currentThread().interrupt();
    510         }
    511         catch (IOException x) {
    512             trouble = true;
    513         }
    514     }
    515 
    516     /*
    517      * The following private methods on the text- and character-output streams
    518      * always flush the stream buffers, so that writes to the underlying byte
    519      * stream occur as promptly as with the original PrintStream.
    520      */
    521 
    522     private void write(char buf[]) {
    523         try {
    524             synchronized (this) {
    525                 ensureOpen();
    526                 // Android-added: Lazy initialization of charOut and textOut.
    527                 BufferedWriter textOut = getTextOut();
    528                 textOut.write(buf);
    529                 textOut.flushBuffer();
    530                 charOut.flushBuffer();
    531                 if (autoFlush) {
    532                     for (int i = 0; i < buf.length; i++)
    533                         if (buf[i] == '\n')
    534                             out.flush();
    535                 }
    536             }
    537         }
    538         catch (InterruptedIOException x) {
    539             Thread.currentThread().interrupt();
    540         }
    541         catch (IOException x) {
    542             trouble = true;
    543         }
    544     }
    545 
    546     private void write(String s) {
    547         try {
    548             synchronized (this) {
    549                 ensureOpen();
    550                 // Android-added: Lazy initialization of charOut and textOut.
    551                 BufferedWriter textOut = getTextOut();
    552                 textOut.write(s);
    553                 textOut.flushBuffer();
    554                 charOut.flushBuffer();
    555                 if (autoFlush && (s.indexOf('\n') >= 0))
    556                     out.flush();
    557             }
    558         }
    559         catch (InterruptedIOException x) {
    560             Thread.currentThread().interrupt();
    561         }
    562         catch (IOException x) {
    563             trouble = true;
    564         }
    565     }
    566 
    567     private void newLine() {
    568         try {
    569             synchronized (this) {
    570                 ensureOpen();
    571                 // Android-added: Lazy initialization of charOut and textOut.
    572                 BufferedWriter textOut = getTextOut();
    573                 textOut.newLine();
    574                 textOut.flushBuffer();
    575                 charOut.flushBuffer();
    576                 if (autoFlush)
    577                     out.flush();
    578             }
    579         }
    580         catch (InterruptedIOException x) {
    581             Thread.currentThread().interrupt();
    582         }
    583         catch (IOException x) {
    584             trouble = true;
    585         }
    586     }
    587 
    588     /* Methods that do not terminate lines */
    589 
    590     /**
    591      * Prints a boolean value.  The string produced by <code>{@link
    592      * java.lang.String#valueOf(boolean)}</code> is translated into bytes
    593      * according to the platform's default character encoding, and these bytes
    594      * are written in exactly the manner of the
    595      * <code>{@link #write(int)}</code> method.
    596      *
    597      * @param      b   The <code>boolean</code> to be printed
    598      */
    599     public void print(boolean b) {
    600         write(b ? "true" : "false");
    601     }
    602 
    603     /**
    604      * Prints a character.  The character is translated into one or more bytes
    605      * according to the platform's default character encoding, and these bytes
    606      * are written in exactly the manner of the
    607      * <code>{@link #write(int)}</code> method.
    608      *
    609      * @param      c   The <code>char</code> to be printed
    610      */
    611     public void print(char c) {
    612         write(String.valueOf(c));
    613     }
    614 
    615     /**
    616      * Prints an integer.  The string produced by <code>{@link
    617      * java.lang.String#valueOf(int)}</code> is translated into bytes
    618      * according to the platform's default character encoding, and these bytes
    619      * are written in exactly the manner of the
    620      * <code>{@link #write(int)}</code> method.
    621      *
    622      * @param      i   The <code>int</code> to be printed
    623      * @see        java.lang.Integer#toString(int)
    624      */
    625     public void print(int i) {
    626         write(String.valueOf(i));
    627     }
    628 
    629     /**
    630      * Prints a long integer.  The string produced by <code>{@link
    631      * java.lang.String#valueOf(long)}</code> is translated into bytes
    632      * according to the platform's default character encoding, and these bytes
    633      * are written in exactly the manner of the
    634      * <code>{@link #write(int)}</code> method.
    635      *
    636      * @param      l   The <code>long</code> to be printed
    637      * @see        java.lang.Long#toString(long)
    638      */
    639     public void print(long l) {
    640         write(String.valueOf(l));
    641     }
    642 
    643     /**
    644      * Prints a floating-point number.  The string produced by <code>{@link
    645      * java.lang.String#valueOf(float)}</code> is translated into bytes
    646      * according to the platform's default character encoding, and these bytes
    647      * are written in exactly the manner of the
    648      * <code>{@link #write(int)}</code> method.
    649      *
    650      * @param      f   The <code>float</code> to be printed
    651      * @see        java.lang.Float#toString(float)
    652      */
    653     public void print(float f) {
    654         write(String.valueOf(f));
    655     }
    656 
    657     /**
    658      * Prints a double-precision floating-point number.  The string produced by
    659      * <code>{@link java.lang.String#valueOf(double)}</code> is translated into
    660      * bytes according to the platform's default character encoding, and these
    661      * bytes are written in exactly the manner of the <code>{@link
    662      * #write(int)}</code> method.
    663      *
    664      * @param      d   The <code>double</code> to be printed
    665      * @see        java.lang.Double#toString(double)
    666      */
    667     public void print(double d) {
    668         write(String.valueOf(d));
    669     }
    670 
    671     /**
    672      * Prints an array of characters.  The characters are converted into bytes
    673      * according to the platform's default character encoding, and these bytes
    674      * are written in exactly the manner of the
    675      * <code>{@link #write(int)}</code> method.
    676      *
    677      * @param      s   The array of chars to be printed
    678      *
    679      * @throws  NullPointerException  If <code>s</code> is <code>null</code>
    680      */
    681     public void print(char s[]) {
    682         write(s);
    683     }
    684 
    685     /**
    686      * Prints a string.  If the argument is <code>null</code> then the string
    687      * <code>"null"</code> is printed.  Otherwise, the string's characters are
    688      * converted into bytes according to the platform's default character
    689      * encoding, and these bytes are written in exactly the manner of the
    690      * <code>{@link #write(int)}</code> method.
    691      *
    692      * @param      s   The <code>String</code> to be printed
    693      */
    694     public void print(String s) {
    695         if (s == null) {
    696             s = "null";
    697         }
    698         write(s);
    699     }
    700 
    701     /**
    702      * Prints an object.  The string produced by the <code>{@link
    703      * java.lang.String#valueOf(Object)}</code> method is translated into bytes
    704      * according to the platform's default character encoding, and these bytes
    705      * are written in exactly the manner of the
    706      * <code>{@link #write(int)}</code> method.
    707      *
    708      * @param      obj   The <code>Object</code> to be printed
    709      * @see        java.lang.Object#toString()
    710      */
    711     public void print(Object obj) {
    712         write(String.valueOf(obj));
    713     }
    714 
    715 
    716     /* Methods that do terminate lines */
    717 
    718     /**
    719      * Terminates the current line by writing the line separator string.  The
    720      * line separator string is defined by the system property
    721      * <code>line.separator</code>, and is not necessarily a single newline
    722      * character (<code>'\n'</code>).
    723      */
    724     public void println() {
    725         newLine();
    726     }
    727 
    728     /**
    729      * Prints a boolean and then terminate the line.  This method behaves as
    730      * though it invokes <code>{@link #print(boolean)}</code> and then
    731      * <code>{@link #println()}</code>.
    732      *
    733      * @param x  The <code>boolean</code> to be printed
    734      */
    735     public void println(boolean x) {
    736         synchronized (this) {
    737             print(x);
    738             newLine();
    739         }
    740     }
    741 
    742     /**
    743      * Prints a character and then terminate the line.  This method behaves as
    744      * though it invokes <code>{@link #print(char)}</code> and then
    745      * <code>{@link #println()}</code>.
    746      *
    747      * @param x  The <code>char</code> to be printed.
    748      */
    749     public void println(char x) {
    750         synchronized (this) {
    751             print(x);
    752             newLine();
    753         }
    754     }
    755 
    756     /**
    757      * Prints an integer and then terminate the line.  This method behaves as
    758      * though it invokes <code>{@link #print(int)}</code> and then
    759      * <code>{@link #println()}</code>.
    760      *
    761      * @param x  The <code>int</code> to be printed.
    762      */
    763     public void println(int x) {
    764         synchronized (this) {
    765             print(x);
    766             newLine();
    767         }
    768     }
    769 
    770     /**
    771      * Prints a long and then terminate the line.  This method behaves as
    772      * though it invokes <code>{@link #print(long)}</code> and then
    773      * <code>{@link #println()}</code>.
    774      *
    775      * @param x  a The <code>long</code> to be printed.
    776      */
    777     public void println(long x) {
    778         synchronized (this) {
    779             print(x);
    780             newLine();
    781         }
    782     }
    783 
    784     /**
    785      * Prints a float and then terminate the line.  This method behaves as
    786      * though it invokes <code>{@link #print(float)}</code> and then
    787      * <code>{@link #println()}</code>.
    788      *
    789      * @param x  The <code>float</code> to be printed.
    790      */
    791     public void println(float x) {
    792         synchronized (this) {
    793             print(x);
    794             newLine();
    795         }
    796     }
    797 
    798     /**
    799      * Prints a double and then terminate the line.  This method behaves as
    800      * though it invokes <code>{@link #print(double)}</code> and then
    801      * <code>{@link #println()}</code>.
    802      *
    803      * @param x  The <code>double</code> to be printed.
    804      */
    805     public void println(double x) {
    806         synchronized (this) {
    807             print(x);
    808             newLine();
    809         }
    810     }
    811 
    812     /**
    813      * Prints an array of characters and then terminate the line.  This method
    814      * behaves as though it invokes <code>{@link #print(char[])}</code> and
    815      * then <code>{@link #println()}</code>.
    816      *
    817      * @param x  an array of chars to print.
    818      */
    819     public void println(char x[]) {
    820         synchronized (this) {
    821             print(x);
    822             newLine();
    823         }
    824     }
    825 
    826     /**
    827      * Prints a String and then terminate the line.  This method behaves as
    828      * though it invokes <code>{@link #print(String)}</code> and then
    829      * <code>{@link #println()}</code>.
    830      *
    831      * @param x  The <code>String</code> to be printed.
    832      */
    833     public void println(String x) {
    834         synchronized (this) {
    835             print(x);
    836             newLine();
    837         }
    838     }
    839 
    840     /**
    841      * Prints an Object and then terminate the line.  This method calls
    842      * at first String.valueOf(x) to get the printed object's string value,
    843      * then behaves as
    844      * though it invokes <code>{@link #print(String)}</code> and then
    845      * <code>{@link #println()}</code>.
    846      *
    847      * @param x  The <code>Object</code> to be printed.
    848      */
    849     public void println(Object x) {
    850         String s = String.valueOf(x);
    851         synchronized (this) {
    852             print(s);
    853             newLine();
    854         }
    855     }
    856 
    857 
    858     /**
    859      * A convenience method to write a formatted string to this output stream
    860      * using the specified format string and arguments.
    861      *
    862      * <p> An invocation of this method of the form <tt>out.printf(format,
    863      * args)</tt> behaves in exactly the same way as the invocation
    864      *
    865      * <pre>
    866      *     out.format(format, args) </pre>
    867      *
    868      * @param  format
    869      *         A format string as described in <a
    870      *         href="../util/Formatter.html#syntax">Format string syntax</a>
    871      *
    872      * @param  args
    873      *         Arguments referenced by the format specifiers in the format
    874      *         string.  If there are more arguments than format specifiers, the
    875      *         extra arguments are ignored.  The number of arguments is
    876      *         variable and may be zero.  The maximum number of arguments is
    877      *         limited by the maximum dimension of a Java array as defined by
    878      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
    879      *         The behaviour on a
    880      *         <tt>null</tt> argument depends on the <a
    881      *         href="../util/Formatter.html#syntax">conversion</a>.
    882      *
    883      * @throws  java.util.IllegalFormatException
    884      *          If a format string contains an illegal syntax, a format
    885      *          specifier that is incompatible with the given arguments,
    886      *          insufficient arguments given the format string, or other
    887      *          illegal conditions.  For specification of all possible
    888      *          formatting errors, see the <a
    889      *          href="../util/Formatter.html#detail">Details</a> section of the
    890      *          formatter class specification.
    891      *
    892      * @throws  NullPointerException
    893      *          If the <tt>format</tt> is <tt>null</tt>
    894      *
    895      * @return  This output stream
    896      *
    897      * @since  1.5
    898      */
    899     public PrintStream printf(String format, Object ... args) {
    900         return format(format, args);
    901     }
    902 
    903     /**
    904      * A convenience method to write a formatted string to this output stream
    905      * using the specified format string and arguments.
    906      *
    907      * <p> An invocation of this method of the form <tt>out.printf(l, format,
    908      * args)</tt> behaves in exactly the same way as the invocation
    909      *
    910      * <pre>
    911      *     out.format(l, format, args) </pre>
    912      *
    913      * @param  l
    914      *         The {@linkplain java.util.Locale locale} to apply during
    915      *         formatting.  If <tt>l</tt> is <tt>null</tt> then no localization
    916      *         is applied.
    917      *
    918      * @param  format
    919      *         A format string as described in <a
    920      *         href="../util/Formatter.html#syntax">Format string syntax</a>
    921      *
    922      * @param  args
    923      *         Arguments referenced by the format specifiers in the format
    924      *         string.  If there are more arguments than format specifiers, the
    925      *         extra arguments are ignored.  The number of arguments is
    926      *         variable and may be zero.  The maximum number of arguments is
    927      *         limited by the maximum dimension of a Java array as defined by
    928      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
    929      *         The behaviour on a
    930      *         <tt>null</tt> argument depends on the <a
    931      *         href="../util/Formatter.html#syntax">conversion</a>.
    932      *
    933      * @throws  java.util.IllegalFormatException
    934      *          If a format string contains an illegal syntax, a format
    935      *          specifier that is incompatible with the given arguments,
    936      *          insufficient arguments given the format string, or other
    937      *          illegal conditions.  For specification of all possible
    938      *          formatting errors, see the <a
    939      *          href="../util/Formatter.html#detail">Details</a> section of the
    940      *          formatter class specification.
    941      *
    942      * @throws  NullPointerException
    943      *          If the <tt>format</tt> is <tt>null</tt>
    944      *
    945      * @return  This output stream
    946      *
    947      * @since  1.5
    948      */
    949     public PrintStream printf(Locale l, String format, Object ... args) {
    950         return format(l, format, args);
    951     }
    952 
    953     /**
    954      * Writes a formatted string to this output stream using the specified
    955      * format string and arguments.
    956      *
    957      * <p> The locale always used is the one returned by {@link
    958      * java.util.Locale#getDefault() Locale.getDefault()}, regardless of any
    959      * previous invocations of other formatting methods on this object.
    960      *
    961      * @param  format
    962      *         A format string as described in <a
    963      *         href="../util/Formatter.html#syntax">Format string syntax</a>
    964      *
    965      * @param  args
    966      *         Arguments referenced by the format specifiers in the format
    967      *         string.  If there are more arguments than format specifiers, the
    968      *         extra arguments are ignored.  The number of arguments is
    969      *         variable and may be zero.  The maximum number of arguments is
    970      *         limited by the maximum dimension of a Java array as defined by
    971      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
    972      *         The behaviour on a
    973      *         <tt>null</tt> argument depends on the <a
    974      *         href="../util/Formatter.html#syntax">conversion</a>.
    975      *
    976      * @throws  java.util.IllegalFormatException
    977      *          If a format string contains an illegal syntax, a format
    978      *          specifier that is incompatible with the given arguments,
    979      *          insufficient arguments given the format string, or other
    980      *          illegal conditions.  For specification of all possible
    981      *          formatting errors, see the <a
    982      *          href="../util/Formatter.html#detail">Details</a> section of the
    983      *          formatter class specification.
    984      *
    985      * @throws  NullPointerException
    986      *          If the <tt>format</tt> is <tt>null</tt>
    987      *
    988      * @return  This output stream
    989      *
    990      * @since  1.5
    991      */
    992     public PrintStream format(String format, Object ... args) {
    993         try {
    994             synchronized (this) {
    995                 ensureOpen();
    996                 if ((formatter == null)
    997                     || (formatter.locale() != Locale.getDefault()))
    998                     formatter = new Formatter((Appendable) this);
    999                 formatter.format(Locale.getDefault(), format, args);
   1000             }
   1001         } catch (InterruptedIOException x) {
   1002             Thread.currentThread().interrupt();
   1003         } catch (IOException x) {
   1004             trouble = true;
   1005         }
   1006         return this;
   1007     }
   1008 
   1009     /**
   1010      * Writes a formatted string to this output stream using the specified
   1011      * format string and arguments.
   1012      *
   1013      * @param  l
   1014      *         The {@linkplain java.util.Locale locale} to apply during
   1015      *         formatting.  If <tt>l</tt> is <tt>null</tt> then no localization
   1016      *         is applied.
   1017      *
   1018      * @param  format
   1019      *         A format string as described in <a
   1020      *         href="../util/Formatter.html#syntax">Format string syntax</a>
   1021      *
   1022      * @param  args
   1023      *         Arguments referenced by the format specifiers in the format
   1024      *         string.  If there are more arguments than format specifiers, the
   1025      *         extra arguments are ignored.  The number of arguments is
   1026      *         variable and may be zero.  The maximum number of arguments is
   1027      *         limited by the maximum dimension of a Java array as defined by
   1028      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   1029      *         The behaviour on a
   1030      *         <tt>null</tt> argument depends on the <a
   1031      *         href="../util/Formatter.html#syntax">conversion</a>.
   1032      *
   1033      * @throws  java.util.IllegalFormatException
   1034      *          If a format string contains an illegal syntax, a format
   1035      *          specifier that is incompatible with the given arguments,
   1036      *          insufficient arguments given the format string, or other
   1037      *          illegal conditions.  For specification of all possible
   1038      *          formatting errors, see the <a
   1039      *          href="../util/Formatter.html#detail">Details</a> section of the
   1040      *          formatter class specification.
   1041      *
   1042      * @throws  NullPointerException
   1043      *          If the <tt>format</tt> is <tt>null</tt>
   1044      *
   1045      * @return  This output stream
   1046      *
   1047      * @since  1.5
   1048      */
   1049     public PrintStream format(Locale l, String format, Object ... args) {
   1050         try {
   1051             synchronized (this) {
   1052                 ensureOpen();
   1053                 if ((formatter == null)
   1054                     || (formatter.locale() != l))
   1055                     formatter = new Formatter(this, l);
   1056                 formatter.format(l, format, args);
   1057             }
   1058         } catch (InterruptedIOException x) {
   1059             Thread.currentThread().interrupt();
   1060         } catch (IOException x) {
   1061             trouble = true;
   1062         }
   1063         return this;
   1064     }
   1065 
   1066     /**
   1067      * Appends the specified character sequence to this output stream.
   1068      *
   1069      * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
   1070      * behaves in exactly the same way as the invocation
   1071      *
   1072      * <pre>
   1073      *     out.print(csq.toString()) </pre>
   1074      *
   1075      * <p> Depending on the specification of <tt>toString</tt> for the
   1076      * character sequence <tt>csq</tt>, the entire sequence may not be
   1077      * appended.  For instance, invoking then <tt>toString</tt> method of a
   1078      * character buffer will return a subsequence whose content depends upon
   1079      * the buffer's position and limit.
   1080      *
   1081      * @param  csq
   1082      *         The character sequence to append.  If <tt>csq</tt> is
   1083      *         <tt>null</tt>, then the four characters <tt>"null"</tt> are
   1084      *         appended to this output stream.
   1085      *
   1086      * @return  This output stream
   1087      *
   1088      * @since  1.5
   1089      */
   1090     public PrintStream append(CharSequence csq) {
   1091         if (csq == null)
   1092             print("null");
   1093         else
   1094             print(csq.toString());
   1095         return this;
   1096     }
   1097 
   1098     /**
   1099      * Appends a subsequence of the specified character sequence to this output
   1100      * stream.
   1101      *
   1102      * <p> An invocation of this method of the form <tt>out.append(csq, start,
   1103      * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
   1104      * exactly the same way as the invocation
   1105      *
   1106      * <pre>
   1107      *     out.print(csq.subSequence(start, end).toString()) </pre>
   1108      *
   1109      * @param  csq
   1110      *         The character sequence from which a subsequence will be
   1111      *         appended.  If <tt>csq</tt> is <tt>null</tt>, then characters
   1112      *         will be appended as if <tt>csq</tt> contained the four
   1113      *         characters <tt>"null"</tt>.
   1114      *
   1115      * @param  start
   1116      *         The index of the first character in the subsequence
   1117      *
   1118      * @param  end
   1119      *         The index of the character following the last character in the
   1120      *         subsequence
   1121      *
   1122      * @return  This output stream
   1123      *
   1124      * @throws  IndexOutOfBoundsException
   1125      *          If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
   1126      *          is greater than <tt>end</tt>, or <tt>end</tt> is greater than
   1127      *          <tt>csq.length()</tt>
   1128      *
   1129      * @since  1.5
   1130      */
   1131     public PrintStream append(CharSequence csq, int start, int end) {
   1132         CharSequence cs = (csq == null ? "null" : csq);
   1133         write(cs.subSequence(start, end).toString());
   1134         return this;
   1135     }
   1136 
   1137     /**
   1138      * Appends the specified character to this output stream.
   1139      *
   1140      * <p> An invocation of this method of the form <tt>out.append(c)</tt>
   1141      * behaves in exactly the same way as the invocation
   1142      *
   1143      * <pre>
   1144      *     out.print(c) </pre>
   1145      *
   1146      * @param  c
   1147      *         The 16-bit character to append
   1148      *
   1149      * @return  This output stream
   1150      *
   1151      * @since  1.5
   1152      */
   1153     public PrintStream append(char c) {
   1154         print(c);
   1155         return this;
   1156     }
   1157 
   1158 }
   1159