< prev index next >

src/java.base/share/classes/java/io/PrintWriter.java

Print this page

  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.Objects;
  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  * Prints formatted representations of objects to a text-output stream.  This
  37  * class implements all of the {@code print} methods found in {@link
  38  * PrintStream}.  It does not contain methods for writing raw bytes, for which
  39  * a program should use unencoded byte streams.
  40  *
  41  * <p> Unlike the {@link PrintStream} class, if automatic flushing is enabled
  42  * it will be done only when one of the {@code println}, {@code printf}, or
  43  * {@code format} methods is invoked, rather than whenever a newline character
  44  * happens to be output.  These methods use the platform's own notion of line
  45  * separator rather than the newline character.
  46  *
  47  * <p> Methods in this class never throw I/O exceptions, although some of its
  48  * constructors may.  The client may inquire as to whether any errors have
  49  * occurred by invoking {@link #checkError checkError()}.
  50  *
  51  * <p> This class always replaces malformed and unmappable character sequences with
  52  * the charset's default replacement string.
  53  * The {@linkplain java.nio.charset.CharsetEncoder} class should be used when more

  78      * @throws NullPointerException          is csn is null
  79      * @throws UnsupportedEncodingException  if the charset is not supported
  80      */
  81     private static Charset toCharset(String csn)
  82         throws UnsupportedEncodingException
  83     {
  84         Objects.requireNonNull(csn, "charsetName");
  85         try {
  86             return Charset.forName(csn);
  87         } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
  88             // UnsupportedEncodingException should be thrown
  89             throw new UnsupportedEncodingException(csn);
  90         }
  91     }
  92 
  93     /**
  94      * Creates a new PrintWriter, without automatic line flushing.
  95      *
  96      * @param  out        A character-output stream
  97      */
  98     public PrintWriter (Writer out) {
  99         this(out, false);
 100     }
 101 
 102     /**
 103      * Creates a new PrintWriter.
 104      *
 105      * @param  out        A character-output stream
 106      * @param  autoFlush  A boolean; if true, the {@code println},
 107      *                    {@code printf}, or {@code format} methods will
 108      *                    flush the output buffer
 109      */
 110     public PrintWriter(Writer out,
 111                        boolean autoFlush) {
 112         super(out);
 113         this.out = out;
 114         this.autoFlush = autoFlush;
 115     }
 116 
 117     /**
 118      * Creates a new PrintWriter, without automatic line flushing, from an
 119      * existing OutputStream.  This convenience constructor creates the
 120      * necessary intermediate OutputStreamWriter, which will convert characters
 121      * into bytes using the default charset.
 122      *
 123      * @param  out        An output stream
 124      *
 125      * @see OutputStreamWriter#OutputStreamWriter(OutputStream)
 126      * @see Charset#defaultCharset()
 127      */
 128     public PrintWriter(OutputStream out) {
 129         this(out, false);
 130     }
 131 
 132     /**
 133      * Creates a new PrintWriter from an existing OutputStream.  This

 375      *          SecurityManager#checkWrite checkWrite(file.getPath())}
 376      *          denies write access to the file
 377      *
 378      * @since  10
 379      */
 380     public PrintWriter(File file, Charset charset) throws IOException {
 381         this(Objects.requireNonNull(charset, "charset"), file);
 382     }
 383 
 384     /** Checks to make sure that the stream has not been closed */
 385     private void ensureOpen() throws IOException {
 386         if (out == null)
 387             throw new IOException("Stream closed");
 388     }
 389 
 390     /**
 391      * Flushes the stream.
 392      * @see #checkError()
 393      */
 394     public void flush() {
 395         try {








 396             synchronized (lock) {
 397                 ensureOpen();
 398                 out.flush();
 399             }
 400         }
 401         catch (IOException x) {






 402             trouble = true;
 403         }
 404     }
 405 
 406     /**
 407      * Closes the stream and releases any system resources associated
 408      * with it. Closing a previously closed stream has no effect.
 409      *
 410      * @see #checkError()
 411      */
 412     public void close() {
 413         try {








 414             synchronized (lock) {
 415                 if (out == null)
 416                     return;






 417                 out.close();
 418                 out = null;
 419             }
 420         }
 421         catch (IOException x) {
 422             trouble = true;
 423         }
 424     }
 425 
 426     /**
 427      * Flushes the stream if it's not closed and checks its error state.
 428      *
 429      * @return {@code true} if the print stream has encountered an error,
 430      *          either on the underlying output stream or during a format
 431      *          conversion.
 432      */
 433     public boolean checkError() {
 434         if (out != null) {
 435             flush();
 436         }
 437         if (out instanceof PrintWriter pw) {
 438             return pw.checkError();
 439         } else if (psOut != null) {
 440             return psOut.checkError();
 441         }

 459      * <p> This method will cause subsequent invocations of {@link
 460      * #checkError()} to return {@code false} until another write
 461      * operation fails and invokes {@link #setError()}.
 462      *
 463      * @since 1.6
 464      */
 465     protected void clearError() {
 466         trouble = false;
 467     }
 468 
 469     /*
 470      * Exception-catching, synchronized output operations,
 471      * which also implement the write() methods of Writer
 472      */
 473 
 474     /**
 475      * Writes a single character.
 476      * @param c int specifying a character to be written.
 477      */
 478     public void write(int c) {
 479         try {








 480             synchronized (lock) {
 481                 ensureOpen();
 482                 out.write(c);
 483             }
 484         }
 485         catch (InterruptedIOException x) {






 486             Thread.currentThread().interrupt();
 487         }
 488         catch (IOException x) {
 489             trouble = true;
 490         }
 491     }
 492 
 493     /**
 494      * Writes A Portion of an array of characters.
 495      * @param buf Array of characters
 496      * @param off Offset from which to start writing characters
 497      * @param len Number of characters to write
 498      *
 499      * @throws  IndexOutOfBoundsException
 500      *          If the values of the {@code off} and {@code len} parameters
 501      *          cause the corresponding method of the underlying {@code Writer}
 502      *          to throw an {@code IndexOutOfBoundsException}
 503      */
 504     public void write(char[] buf, int off, int len) {
 505         try {








 506             synchronized (lock) {
 507                 ensureOpen();
 508                 out.write(buf, off, len);
 509             }
 510         }
 511         catch (InterruptedIOException x) {






 512             Thread.currentThread().interrupt();
 513         }
 514         catch (IOException x) {
 515             trouble = true;
 516         }
 517     }
 518 
 519     /**
 520      * Writes an array of characters.  This method cannot be inherited from the
 521      * Writer class because it must suppress I/O exceptions.
 522      * @param buf Array of characters to be written
 523      */
 524     public void write(char[] buf) {
 525         write(buf, 0, buf.length);
 526     }
 527 
 528     /**
 529      * Writes a portion of a string.
 530      * @param s A String
 531      * @param off Offset from which to start writing characters
 532      * @param len Number of characters to write
 533      *
 534      * @throws  IndexOutOfBoundsException
 535      *          If the values of the {@code off} and {@code len} parameters
 536      *          cause the corresponding method of the underlying {@code Writer}
 537      *          to throw an {@code IndexOutOfBoundsException}
 538      */
 539     public void write(String s, int off, int len) {
 540         try {








 541             synchronized (lock) {
 542                 ensureOpen();
 543                 out.write(s, off, len);
 544             }
 545         }
 546         catch (InterruptedIOException x) {






 547             Thread.currentThread().interrupt();
 548         }
 549         catch (IOException x) {
 550             trouble = true;
 551         }
 552     }
 553 
 554     /**
 555      * Writes a string.  This method cannot be inherited from the Writer class
 556      * because it must suppress I/O exceptions.
 557      * @param s String to be written
 558      */
 559     public void write(String s) {
 560         write(s, 0, s.length());
 561     }
 562 
 563     private void newLine() {
 564         try {








 565             synchronized (lock) {
 566                 ensureOpen();
 567                 out.write(System.lineSeparator());
 568                 if (autoFlush)
 569                     out.flush();
 570             }
 571         }
 572         catch (InterruptedIOException x) {








 573             Thread.currentThread().interrupt();
 574         }
 575         catch (IOException x) {
 576             trouble = true;
 577         }
 578     }
 579 
 580     /* Methods that do not terminate lines */
 581 
 582     /**
 583      * Prints a boolean value.  The string produced by {@link
 584      * java.lang.String#valueOf(boolean)} is translated into bytes
 585      * according to the default charset, and these bytes
 586      * are written in exactly the manner of the {@link
 587      * #write(int)} method.
 588      *
 589      * @param      b   The {@code boolean} to be printed
 590      * @see Charset#defaultCharset()
 591      */
 592     public void print(boolean b) {
 593         write(String.valueOf(b));
 594     }
 595 

 712 
 713     /* Methods that do terminate lines */
 714 
 715     /**
 716      * Terminates the current line by writing the line separator string.  The
 717      * line separator is {@link System#lineSeparator()} and is not necessarily
 718      * a single newline character ({@code '\n'}).
 719      */
 720     public void println() {
 721         newLine();
 722     }
 723 
 724     /**
 725      * Prints a boolean value and then terminates the line.  This method behaves
 726      * as though it invokes {@link #print(boolean)} and then
 727      * {@link #println()}.
 728      *
 729      * @param x the {@code boolean} value to be printed
 730      */
 731     public void println(boolean x) {
 732         synchronized (lock) {
 733             print(x);
 734             println();











 735         }
 736     }
 737 
 738     /**
 739      * Prints a character and then terminates the line.  This method behaves as
 740      * though it invokes {@link #print(char)} and then {@link
 741      * #println()}.
 742      *
 743      * @param x the {@code char} value to be printed
 744      */
 745     public void println(char x) {
 746         synchronized (lock) {
 747             print(x);
 748             println();











 749         }
 750     }
 751 
 752     /**
 753      * Prints an integer and then terminates the line.  This method behaves as
 754      * though it invokes {@link #print(int)} and then {@link
 755      * #println()}.
 756      *
 757      * @param x the {@code int} value to be printed
 758      */
 759     public void println(int x) {
 760         synchronized (lock) {
 761             print(x);
 762             println();











 763         }
 764     }
 765 
 766     /**
 767      * Prints a long integer and then terminates the line.  This method behaves
 768      * as though it invokes {@link #print(long)} and then
 769      * {@link #println()}.
 770      *
 771      * @param x the {@code long} value to be printed
 772      */
 773     public void println(long x) {
 774         synchronized (lock) {
 775             print(x);
 776             println();











 777         }
 778     }
 779 
 780     /**
 781      * Prints a floating-point number and then terminates the line.  This method
 782      * behaves as though it invokes {@link #print(float)} and then
 783      * {@link #println()}.
 784      *
 785      * @param x the {@code float} value to be printed
 786      */
 787     public void println(float x) {
 788         synchronized (lock) {
 789             print(x);
 790             println();











 791         }
 792     }
 793 
 794     /**
 795      * Prints a double-precision floating-point number and then terminates the
 796      * line.  This method behaves as though it invokes {@link
 797      * #print(double)} and then {@link #println()}.
 798      *
 799      * @param x the {@code double} value to be printed
 800      */
 801     public void println(double x) {
 802         synchronized (lock) {
 803             print(x);
 804             println();











 805         }
 806     }
 807 
 808     /**
 809      * Prints an array of characters and then terminates the line.  This method
 810      * behaves as though it invokes {@link #print(char[])} and then
 811      * {@link #println()}.
 812      *
 813      * @param x the array of {@code char} values to be printed
 814      */
 815     public void println(char[] x) {
 816         synchronized (lock) {
 817             print(x);
 818             println();











 819         }
 820     }
 821 
 822     /**
 823      * Prints a String and then terminates the line.  This method behaves as
 824      * though it invokes {@link #print(String)} and then
 825      * {@link #println()}.
 826      *
 827      * @param x the {@code String} value to be printed
 828      */
 829     public void println(String x) {
 830         synchronized (lock) {
 831             print(x);
 832             println();











 833         }
 834     }
 835 
 836     /**
 837      * Prints an Object and then terminates the line.  This method calls
 838      * at first String.valueOf(x) to get the printed object's string value,
 839      * then behaves as
 840      * though it invokes {@link #print(String)} and then
 841      * {@link #println()}.
 842      *
 843      * @param x  The {@code Object} to be printed.
 844      */
 845     public void println(Object x) {
 846         String s = String.valueOf(x);
 847         synchronized (lock) {
 848             print(s);
 849             println();











 850         }
 851     }
 852 
 853     /**
 854      * A convenience method to write a formatted string to this writer using
 855      * the specified format string and arguments.  If automatic flushing is
 856      * enabled, calls to this method will flush the output buffer.
 857      *
 858      * <p> An invocation of this method of the form
 859      * {@code out.printf(format, args)}
 860      * behaves in exactly the same way as the invocation
 861      *
 862      * <pre>{@code
 863      *     out.format(format, args)
 864      * }</pre>
 865      *
 866      * @param  format
 867      *         A format string as described in <a
 868      *         href="../util/Formatter.html#syntax">Format string syntax</a>.
 869      *

 975      *         {@code null} argument depends on the <a
 976      *         href="../util/Formatter.html#syntax">conversion</a>.
 977      *
 978      * @throws  java.util.IllegalFormatException
 979      *          If a format string contains an illegal syntax, a format
 980      *          specifier that is incompatible with the given arguments,
 981      *          insufficient arguments given the format string, or other
 982      *          illegal conditions.  For specification of all possible
 983      *          formatting errors, see the <a
 984      *          href="../util/Formatter.html#detail">Details</a> section of the
 985      *          Formatter class specification.
 986      *
 987      * @throws  NullPointerException
 988      *          If the {@code format} is {@code null}
 989      *
 990      * @return  This writer
 991      *
 992      * @since  1.5
 993      */
 994     public PrintWriter format(String format, Object ... args) {
 995         try {








 996             synchronized (lock) {
 997                 ensureOpen();
 998                 if ((formatter == null)
 999                     || (formatter.locale() != Locale.getDefault()))
1000                     formatter = new Formatter(this);
1001                 formatter.format(Locale.getDefault(), format, args);
1002                 if (autoFlush)
1003                     out.flush();
1004             }













1005         } catch (InterruptedIOException x) {
1006             Thread.currentThread().interrupt();
1007         } catch (IOException x) {
1008             trouble = true;
1009         }
1010         return this;
1011     }
1012 
1013     /**
1014      * Writes a formatted string to this writer using the specified format
1015      * string and arguments.  If automatic flushing is enabled, calls to this
1016      * method will flush the output buffer.
1017      *
1018      * @param  l
1019      *         The {@linkplain java.util.Locale locale} to apply during
1020      *         formatting.  If {@code l} is {@code null} then no localization
1021      *         is applied.
1022      *
1023      * @param  format
1024      *         A format string as described in <a
1025      *         href="../util/Formatter.html#syntax">Format string syntax</a>.
1026      *
1027      * @param  args
1028      *         Arguments referenced by the format specifiers in the format
1029      *         string.  If there are more arguments than format specifiers, the
1030      *         extra arguments are ignored.  The number of arguments is

1035      *         {@code null} argument depends on the <a
1036      *         href="../util/Formatter.html#syntax">conversion</a>.
1037      *
1038      * @throws  java.util.IllegalFormatException
1039      *          If a format string contains an illegal syntax, a format
1040      *          specifier that is incompatible with the given arguments,
1041      *          insufficient arguments given the format string, or other
1042      *          illegal conditions.  For specification of all possible
1043      *          formatting errors, see the <a
1044      *          href="../util/Formatter.html#detail">Details</a> section of the
1045      *          formatter class specification.
1046      *
1047      * @throws  NullPointerException
1048      *          If the {@code format} is {@code null}
1049      *
1050      * @return  This writer
1051      *
1052      * @since  1.5
1053      */
1054     public PrintWriter format(Locale l, String format, Object ... args) {
1055         try {








1056             synchronized (lock) {
1057                 ensureOpen();
1058                 if ((formatter == null) || (formatter.locale() != l))
1059                     formatter = new Formatter(this, l);
1060                 formatter.format(l, format, args);
1061                 if (autoFlush)
1062                     out.flush();
1063             }












1064         } catch (InterruptedIOException x) {
1065             Thread.currentThread().interrupt();
1066         } catch (IOException x) {
1067             trouble = true;
1068         }
1069         return this;
1070     }
1071 
1072     /**
1073      * Appends the specified character sequence to this writer.
1074      *
1075      * <p> An invocation of this method of the form {@code out.append(csq)}
1076      * behaves in exactly the same way as the invocation
1077      *
1078      * <pre>{@code
1079      *     out.write(csq.toString())
1080      * }</pre>
1081      *
1082      * <p> Depending on the specification of {@code toString} for the
1083      * character sequence {@code csq}, the entire sequence may not be
1084      * appended. For instance, invoking the {@code toString} method of a
1085      * character buffer will return a subsequence whose content depends upon
1086      * the buffer's position and limit.
1087      *
1088      * @param  csq
1089      *         The character sequence to append.  If {@code csq} is

1142      * Appends the specified character to this writer.
1143      *
1144      * <p> An invocation of this method of the form {@code out.append(c)}
1145      * behaves in exactly the same way as the invocation
1146      *
1147      * <pre>{@code
1148      *     out.write(c)
1149      * }</pre>
1150      *
1151      * @param  c
1152      *         The 16-bit character to append
1153      *
1154      * @return  This writer
1155      *
1156      * @since 1.5
1157      */
1158     public PrintWriter append(char c) {
1159         write(c);
1160         return this;
1161     }








1162 }

  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.Objects;
  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 import jdk.internal.access.JavaIOPrintWriterAccess;
  35 import jdk.internal.access.SharedSecrets;
  36 import jdk.internal.misc.InternalLock;
  37 
  38 /**
  39  * Prints formatted representations of objects to a text-output stream.  This
  40  * class implements all of the {@code print} methods found in {@link
  41  * PrintStream}.  It does not contain methods for writing raw bytes, for which
  42  * a program should use unencoded byte streams.
  43  *
  44  * <p> Unlike the {@link PrintStream} class, if automatic flushing is enabled
  45  * it will be done only when one of the {@code println}, {@code printf}, or
  46  * {@code format} methods is invoked, rather than whenever a newline character
  47  * happens to be output.  These methods use the platform's own notion of line
  48  * separator rather than the newline character.
  49  *
  50  * <p> Methods in this class never throw I/O exceptions, although some of its
  51  * constructors may.  The client may inquire as to whether any errors have
  52  * occurred by invoking {@link #checkError checkError()}.
  53  *
  54  * <p> This class always replaces malformed and unmappable character sequences with
  55  * the charset's default replacement string.
  56  * The {@linkplain java.nio.charset.CharsetEncoder} class should be used when more

  81      * @throws NullPointerException          is csn is null
  82      * @throws UnsupportedEncodingException  if the charset is not supported
  83      */
  84     private static Charset toCharset(String csn)
  85         throws UnsupportedEncodingException
  86     {
  87         Objects.requireNonNull(csn, "charsetName");
  88         try {
  89             return Charset.forName(csn);
  90         } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
  91             // UnsupportedEncodingException should be thrown
  92             throw new UnsupportedEncodingException(csn);
  93         }
  94     }
  95 
  96     /**
  97      * Creates a new PrintWriter, without automatic line flushing.
  98      *
  99      * @param  out        A character-output stream
 100      */
 101     public PrintWriter(Writer out) {
 102         this(out, false);
 103     }
 104 
 105     /**
 106      * Creates a new PrintWriter.
 107      *
 108      * @param  out        A character-output stream
 109      * @param  autoFlush  A boolean; if true, the {@code println},
 110      *                    {@code printf}, or {@code format} methods will
 111      *                    flush the output buffer
 112      */
 113     public PrintWriter(Writer out, boolean autoFlush) {
 114         this.out = Objects.requireNonNull(out);


 115         this.autoFlush = autoFlush;
 116     }
 117 
 118     /**
 119      * Creates a new PrintWriter, without automatic line flushing, from an
 120      * existing OutputStream.  This convenience constructor creates the
 121      * necessary intermediate OutputStreamWriter, which will convert characters
 122      * into bytes using the default charset.
 123      *
 124      * @param  out        An output stream
 125      *
 126      * @see OutputStreamWriter#OutputStreamWriter(OutputStream)
 127      * @see Charset#defaultCharset()
 128      */
 129     public PrintWriter(OutputStream out) {
 130         this(out, false);
 131     }
 132 
 133     /**
 134      * Creates a new PrintWriter from an existing OutputStream.  This

 376      *          SecurityManager#checkWrite checkWrite(file.getPath())}
 377      *          denies write access to the file
 378      *
 379      * @since  10
 380      */
 381     public PrintWriter(File file, Charset charset) throws IOException {
 382         this(Objects.requireNonNull(charset, "charset"), file);
 383     }
 384 
 385     /** Checks to make sure that the stream has not been closed */
 386     private void ensureOpen() throws IOException {
 387         if (out == null)
 388             throw new IOException("Stream closed");
 389     }
 390 
 391     /**
 392      * Flushes the stream.
 393      * @see #checkError()
 394      */
 395     public void flush() {
 396         Object lock = this.lock;
 397         if (lock instanceof InternalLock locker) {
 398             locker.lock();
 399             try {
 400                 lockedFlush();
 401             } finally {
 402                 locker.unlock();
 403             }
 404         } else {
 405             synchronized (lock) {
 406                 lockedFlush();

 407             }
 408         }
 409     }
 410 
 411     private void lockedFlush() {
 412         try {
 413             ensureOpen();
 414             out.flush();
 415         } catch (IOException x) {
 416             trouble = true;
 417         }
 418     }
 419 
 420     /**
 421      * Closes the stream and releases any system resources associated
 422      * with it. Closing a previously closed stream has no effect.
 423      *
 424      * @see #checkError()
 425      */
 426     public void close() {
 427         Object lock = this.lock;
 428         if (lock instanceof InternalLock locker) {
 429             locker.lock();
 430             try {
 431                 lockedClose();
 432             } finally {
 433                 locker.unlock();
 434             }
 435         } else {
 436             synchronized (lock) {
 437                 lockedClose();
 438             }
 439         }
 440     }
 441 
 442     private void lockedClose() {
 443         try {
 444             if (out != null) {
 445                 out.close();
 446                 out = null;
 447             }
 448         } catch (IOException x) {

 449             trouble = true;
 450         }
 451     }
 452 
 453     /**
 454      * Flushes the stream if it's not closed and checks its error state.
 455      *
 456      * @return {@code true} if the print stream has encountered an error,
 457      *          either on the underlying output stream or during a format
 458      *          conversion.
 459      */
 460     public boolean checkError() {
 461         if (out != null) {
 462             flush();
 463         }
 464         if (out instanceof PrintWriter pw) {
 465             return pw.checkError();
 466         } else if (psOut != null) {
 467             return psOut.checkError();
 468         }

 486      * <p> This method will cause subsequent invocations of {@link
 487      * #checkError()} to return {@code false} until another write
 488      * operation fails and invokes {@link #setError()}.
 489      *
 490      * @since 1.6
 491      */
 492     protected void clearError() {
 493         trouble = false;
 494     }
 495 
 496     /*
 497      * Exception-catching, synchronized output operations,
 498      * which also implement the write() methods of Writer
 499      */
 500 
 501     /**
 502      * Writes a single character.
 503      * @param c int specifying a character to be written.
 504      */
 505     public void write(int c) {
 506         Object lock = this.lock;
 507         if (lock instanceof InternalLock locker) {
 508             locker.lock();
 509             try {
 510                 lockedWrite(c);
 511             } finally {
 512                 locker.unlock();
 513             }
 514         } else {
 515             synchronized (lock) {
 516                 lockedWrite(c);

 517             }
 518         }
 519     }
 520 
 521     private void lockedWrite(int c) {
 522         try {
 523             ensureOpen();
 524             out.write(c);
 525         } catch (InterruptedIOException x) {
 526             Thread.currentThread().interrupt();
 527         } catch (IOException x) {

 528             trouble = true;
 529         }
 530     }
 531 
 532     /**
 533      * Writes A Portion of an array of characters.
 534      * @param buf Array of characters
 535      * @param off Offset from which to start writing characters
 536      * @param len Number of characters to write
 537      *
 538      * @throws  IndexOutOfBoundsException
 539      *          If the values of the {@code off} and {@code len} parameters
 540      *          cause the corresponding method of the underlying {@code Writer}
 541      *          to throw an {@code IndexOutOfBoundsException}
 542      */
 543     public void write(char[] buf, int off, int len) {
 544         Object lock = this.lock;
 545         if (lock instanceof InternalLock locker) {
 546             locker.lock();
 547             try {
 548                 lockedWrite(buf, off, len);
 549             } finally {
 550                 locker.unlock();
 551             }
 552         } else {
 553             synchronized (lock) {
 554                 lockedWrite(buf, off, len);

 555             }
 556         }
 557     }
 558 
 559     private void lockedWrite(char[] buf, int off, int len) {
 560         try {
 561             ensureOpen();
 562             out.write(buf, off, len);
 563         } catch (InterruptedIOException x) {
 564             Thread.currentThread().interrupt();
 565         } catch (IOException x) {

 566             trouble = true;
 567         }
 568     }
 569 
 570     /**
 571      * Writes an array of characters.  This method cannot be inherited from the
 572      * Writer class because it must suppress I/O exceptions.
 573      * @param buf Array of characters to be written
 574      */
 575     public void write(char[] buf) {
 576         write(buf, 0, buf.length);
 577     }
 578 
 579     /**
 580      * Writes a portion of a string.
 581      * @param s A String
 582      * @param off Offset from which to start writing characters
 583      * @param len Number of characters to write
 584      *
 585      * @throws  IndexOutOfBoundsException
 586      *          If the values of the {@code off} and {@code len} parameters
 587      *          cause the corresponding method of the underlying {@code Writer}
 588      *          to throw an {@code IndexOutOfBoundsException}
 589      */
 590     public void write(String s, int off, int len) {
 591         Object lock = this.lock;
 592         if (lock instanceof InternalLock locker) {
 593             locker.lock();
 594             try {
 595                 lockedWrite(s, off, len);
 596             } finally {
 597                 locker.unlock();
 598             }
 599         } else {
 600             synchronized (lock) {
 601                 lockedWrite(s, off, len);

 602             }
 603         }
 604     }
 605 
 606     private void lockedWrite(String s, int off, int len) {
 607         try {
 608             ensureOpen();
 609             out.write(s, off, len);
 610         } catch (InterruptedIOException x) {
 611             Thread.currentThread().interrupt();
 612         } catch (IOException x) {

 613             trouble = true;
 614         }
 615     }
 616 
 617     /**
 618      * Writes a string.  This method cannot be inherited from the Writer class
 619      * because it must suppress I/O exceptions.
 620      * @param s String to be written
 621      */
 622     public void write(String s) {
 623         write(s, 0, s.length());
 624     }
 625 
 626     private void newLine() {
 627         Object lock = this.lock;
 628         if (lock instanceof InternalLock locker) {
 629             locker.lock();
 630             try {
 631                 lockedNewLine();
 632             } finally {
 633                 locker.unlock();
 634             }
 635         } else {
 636             synchronized (lock) {
 637                 lockedNewLine();



 638             }
 639         }
 640     }
 641 
 642     private void lockedNewLine() {
 643         try {
 644             ensureOpen();
 645             out.write(System.lineSeparator());
 646             if (autoFlush)
 647                 out.flush();
 648         } catch (InterruptedIOException x) {
 649             Thread.currentThread().interrupt();
 650         } catch (IOException x) {

 651             trouble = true;
 652         }
 653     }
 654 
 655     /* Methods that do not terminate lines */
 656 
 657     /**
 658      * Prints a boolean value.  The string produced by {@link
 659      * java.lang.String#valueOf(boolean)} is translated into bytes
 660      * according to the default charset, and these bytes
 661      * are written in exactly the manner of the {@link
 662      * #write(int)} method.
 663      *
 664      * @param      b   The {@code boolean} to be printed
 665      * @see Charset#defaultCharset()
 666      */
 667     public void print(boolean b) {
 668         write(String.valueOf(b));
 669     }
 670 

 787 
 788     /* Methods that do terminate lines */
 789 
 790     /**
 791      * Terminates the current line by writing the line separator string.  The
 792      * line separator is {@link System#lineSeparator()} and is not necessarily
 793      * a single newline character ({@code '\n'}).
 794      */
 795     public void println() {
 796         newLine();
 797     }
 798 
 799     /**
 800      * Prints a boolean value and then terminates the line.  This method behaves
 801      * as though it invokes {@link #print(boolean)} and then
 802      * {@link #println()}.
 803      *
 804      * @param x the {@code boolean} value to be printed
 805      */
 806     public void println(boolean x) {
 807         Object lock = this.lock;
 808         if (lock instanceof InternalLock locker) {
 809             locker.lock();
 810             try {
 811                 print(x);
 812                 println();
 813             } finally {
 814                 locker.unlock();
 815             }
 816         } else {
 817             synchronized (lock) {
 818                 print(x);
 819                 println();
 820             }
 821         }
 822     }
 823 
 824     /**
 825      * Prints a character and then terminates the line.  This method behaves as
 826      * though it invokes {@link #print(char)} and then {@link
 827      * #println()}.
 828      *
 829      * @param x the {@code char} value to be printed
 830      */
 831     public void println(char x) {
 832         Object lock = this.lock;
 833         if (lock instanceof InternalLock locker) {
 834             locker.lock();
 835             try {
 836                 print(x);
 837                 println();
 838             } finally {
 839                 locker.unlock();
 840             }
 841         } else {
 842             synchronized (lock) {
 843                 print(x);
 844                 println();
 845             }
 846         }
 847     }
 848 
 849     /**
 850      * Prints an integer and then terminates the line.  This method behaves as
 851      * though it invokes {@link #print(int)} and then {@link
 852      * #println()}.
 853      *
 854      * @param x the {@code int} value to be printed
 855      */
 856     public void println(int x) {
 857         Object lock = this.lock;
 858         if (lock instanceof InternalLock locker) {
 859             locker.lock();
 860             try {
 861                 print(x);
 862                 println();
 863             } finally {
 864                 locker.unlock();
 865             }
 866         } else {
 867             synchronized (lock) {
 868                 print(x);
 869                 println();
 870             }
 871         }
 872     }
 873 
 874     /**
 875      * Prints a long integer and then terminates the line.  This method behaves
 876      * as though it invokes {@link #print(long)} and then
 877      * {@link #println()}.
 878      *
 879      * @param x the {@code long} value to be printed
 880      */
 881     public void println(long x) {
 882         Object lock = this.lock;
 883         if (lock instanceof InternalLock locker) {
 884             locker.lock();
 885             try {
 886                 print(x);
 887                 println();
 888             } finally {
 889                 locker.unlock();
 890             }
 891         } else {
 892             synchronized (lock) {
 893                 print(x);
 894                 println();
 895             }
 896         }
 897     }
 898 
 899     /**
 900      * Prints a floating-point number and then terminates the line.  This method
 901      * behaves as though it invokes {@link #print(float)} and then
 902      * {@link #println()}.
 903      *
 904      * @param x the {@code float} value to be printed
 905      */
 906     public void println(float x) {
 907         Object lock = this.lock;
 908         if (lock instanceof InternalLock locker) {
 909             locker.lock();
 910             try {
 911                 print(x);
 912                 println();
 913             } finally {
 914                 locker.unlock();
 915             }
 916         } else {
 917             synchronized (lock) {
 918                 print(x);
 919                 println();
 920             }
 921         }
 922     }
 923 
 924     /**
 925      * Prints a double-precision floating-point number and then terminates the
 926      * line.  This method behaves as though it invokes {@link
 927      * #print(double)} and then {@link #println()}.
 928      *
 929      * @param x the {@code double} value to be printed
 930      */
 931     public void println(double x) {
 932         Object lock = this.lock;
 933         if (lock instanceof InternalLock locker) {
 934             locker.lock();
 935             try {
 936                 print(x);
 937                 println();
 938             } finally {
 939                 locker.unlock();
 940             }
 941         } else {
 942             synchronized (lock) {
 943                 print(x);
 944                 println();
 945             }
 946         }
 947     }
 948 
 949     /**
 950      * Prints an array of characters and then terminates the line.  This method
 951      * behaves as though it invokes {@link #print(char[])} and then
 952      * {@link #println()}.
 953      *
 954      * @param x the array of {@code char} values to be printed
 955      */
 956     public void println(char[] x) {
 957         Object lock = this.lock;
 958         if (lock instanceof InternalLock locker) {
 959             locker.lock();
 960             try {
 961                 print(x);
 962                 println();
 963             } finally {
 964                 locker.unlock();
 965             }
 966         } else {
 967             synchronized (lock) {
 968                 print(x);
 969                 println();
 970             }
 971         }
 972     }
 973 
 974     /**
 975      * Prints a String and then terminates the line.  This method behaves as
 976      * though it invokes {@link #print(String)} and then
 977      * {@link #println()}.
 978      *
 979      * @param x the {@code String} value to be printed
 980      */
 981     public void println(String x) {
 982         Object lock = this.lock;
 983         if (lock instanceof InternalLock locker) {
 984             locker.lock();
 985             try {
 986                 print(x);
 987                 println();
 988             } finally {
 989                 locker.unlock();
 990             }
 991         } else {
 992             synchronized (lock) {
 993                 print(x);
 994                 println();
 995             }
 996         }
 997     }
 998 
 999     /**
1000      * Prints an Object and then terminates the line.  This method calls
1001      * at first String.valueOf(x) to get the printed object's string value,
1002      * then behaves as
1003      * though it invokes {@link #print(String)} and then
1004      * {@link #println()}.
1005      *
1006      * @param x  The {@code Object} to be printed.
1007      */
1008     public void println(Object x) {
1009         String s = String.valueOf(x);
1010         Object lock = this.lock;
1011         if (lock instanceof InternalLock locker) {
1012             locker.lock();
1013             try {
1014                 print(s);
1015                 println();
1016             } finally {
1017                 locker.unlock();
1018             }
1019         } else {
1020             synchronized (lock) {
1021                 print(s);
1022                 println();
1023             }
1024         }
1025     }
1026 
1027     /**
1028      * A convenience method to write a formatted string to this writer using
1029      * the specified format string and arguments.  If automatic flushing is
1030      * enabled, calls to this method will flush the output buffer.
1031      *
1032      * <p> An invocation of this method of the form
1033      * {@code out.printf(format, args)}
1034      * behaves in exactly the same way as the invocation
1035      *
1036      * <pre>{@code
1037      *     out.format(format, args)
1038      * }</pre>
1039      *
1040      * @param  format
1041      *         A format string as described in <a
1042      *         href="../util/Formatter.html#syntax">Format string syntax</a>.
1043      *

1149      *         {@code null} argument depends on the <a
1150      *         href="../util/Formatter.html#syntax">conversion</a>.
1151      *
1152      * @throws  java.util.IllegalFormatException
1153      *          If a format string contains an illegal syntax, a format
1154      *          specifier that is incompatible with the given arguments,
1155      *          insufficient arguments given the format string, or other
1156      *          illegal conditions.  For specification of all possible
1157      *          formatting errors, see the <a
1158      *          href="../util/Formatter.html#detail">Details</a> section of the
1159      *          Formatter class specification.
1160      *
1161      * @throws  NullPointerException
1162      *          If the {@code format} is {@code null}
1163      *
1164      * @return  This writer
1165      *
1166      * @since  1.5
1167      */
1168     public PrintWriter format(String format, Object ... args) {
1169         Object lock = this.lock;
1170         if (lock instanceof InternalLock locker) {
1171             locker.lock();
1172             try {
1173                 lockedFormat(format, args);
1174             } finally {
1175                 locker.unlock();
1176             }
1177         } else {
1178             synchronized (lock) {
1179                 lockedFormat(format, args);






1180             }
1181         }
1182         return this;
1183     }
1184 
1185     private void lockedFormat(String format, Object ... args) {
1186         try {
1187             ensureOpen();
1188             if ((formatter == null)
1189                 || (formatter.locale() != Locale.getDefault()))
1190                 formatter = new Formatter(this);
1191             formatter.format(Locale.getDefault(), format, args);
1192             if (autoFlush)
1193                 out.flush();
1194         } catch (InterruptedIOException x) {
1195             Thread.currentThread().interrupt();
1196         } catch (IOException x) {
1197             trouble = true;
1198         }

1199     }
1200 
1201     /**
1202      * Writes a formatted string to this writer using the specified format
1203      * string and arguments.  If automatic flushing is enabled, calls to this
1204      * method will flush the output buffer.
1205      *
1206      * @param  l
1207      *         The {@linkplain java.util.Locale locale} to apply during
1208      *         formatting.  If {@code l} is {@code null} then no localization
1209      *         is applied.
1210      *
1211      * @param  format
1212      *         A format string as described in <a
1213      *         href="../util/Formatter.html#syntax">Format string syntax</a>.
1214      *
1215      * @param  args
1216      *         Arguments referenced by the format specifiers in the format
1217      *         string.  If there are more arguments than format specifiers, the
1218      *         extra arguments are ignored.  The number of arguments is

1223      *         {@code null} argument depends on the <a
1224      *         href="../util/Formatter.html#syntax">conversion</a>.
1225      *
1226      * @throws  java.util.IllegalFormatException
1227      *          If a format string contains an illegal syntax, a format
1228      *          specifier that is incompatible with the given arguments,
1229      *          insufficient arguments given the format string, or other
1230      *          illegal conditions.  For specification of all possible
1231      *          formatting errors, see the <a
1232      *          href="../util/Formatter.html#detail">Details</a> section of the
1233      *          formatter class specification.
1234      *
1235      * @throws  NullPointerException
1236      *          If the {@code format} is {@code null}
1237      *
1238      * @return  This writer
1239      *
1240      * @since  1.5
1241      */
1242     public PrintWriter format(Locale l, String format, Object ... args) {
1243         Object lock = this.lock;
1244         if (lock instanceof InternalLock locker) {
1245             locker.lock();
1246             try {
1247                 lockedFormat(l, format, args);
1248             } finally {
1249                 locker.unlock();
1250             }
1251         } else {
1252             synchronized (lock) {
1253                 lockedFormat(l, format, args);





1254             }
1255         }
1256         return this;
1257     }
1258 
1259     private void lockedFormat(Locale l, String format, Object ... args) {
1260         try {
1261             ensureOpen();
1262             if ((formatter == null) || (formatter.locale() != l))
1263                 formatter = new Formatter(this, l);
1264             formatter.format(l, format, args);
1265             if (autoFlush)
1266                 out.flush();
1267         } catch (InterruptedIOException x) {
1268             Thread.currentThread().interrupt();
1269         } catch (IOException x) {
1270             trouble = true;
1271         }

1272     }
1273 
1274     /**
1275      * Appends the specified character sequence to this writer.
1276      *
1277      * <p> An invocation of this method of the form {@code out.append(csq)}
1278      * behaves in exactly the same way as the invocation
1279      *
1280      * <pre>{@code
1281      *     out.write(csq.toString())
1282      * }</pre>
1283      *
1284      * <p> Depending on the specification of {@code toString} for the
1285      * character sequence {@code csq}, the entire sequence may not be
1286      * appended. For instance, invoking the {@code toString} method of a
1287      * character buffer will return a subsequence whose content depends upon
1288      * the buffer's position and limit.
1289      *
1290      * @param  csq
1291      *         The character sequence to append.  If {@code csq} is

1344      * Appends the specified character to this writer.
1345      *
1346      * <p> An invocation of this method of the form {@code out.append(c)}
1347      * behaves in exactly the same way as the invocation
1348      *
1349      * <pre>{@code
1350      *     out.write(c)
1351      * }</pre>
1352      *
1353      * @param  c
1354      *         The 16-bit character to append
1355      *
1356      * @return  This writer
1357      *
1358      * @since 1.5
1359      */
1360     public PrintWriter append(char c) {
1361         write(c);
1362         return this;
1363     }
1364 
1365     static {
1366         SharedSecrets.setJavaIOCPrintWriterAccess(new JavaIOPrintWriterAccess() {
1367             public Object lock(PrintWriter pw) {
1368                 return pw.lock;
1369             }
1370         });
1371     }
1372 }
< prev index next >