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