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 @Override 419 public void flush() { 420 synchronized (this) { 421 try { 422 ensureOpen(); 423 out.flush(); 424 } 425 catch (IOException x) { 426 trouble = true; 427 } 428 } 429 } 430 431 private boolean closing = false; /* To avoid recursive closing */ 432 433 /** 434 * Closes the stream. This is done by flushing the stream and then closing 435 * the underlying output stream. 436 * 437 * @see java.io.OutputStream#close() 438 */ 439 @Override 440 public void close() { 441 synchronized (this) { 442 if (! closing) { 443 closing = true; 444 try { 445 textOut.close(); 446 out.close(); 447 } 448 catch (IOException x) { 449 trouble = true; 450 } 451 textOut = null; 452 charOut = null; 453 out = null; 454 } 455 } 456 } 457 458 /** 459 * Flushes the stream and checks its error state. The internal error state 460 * is set to {@code true} when the underlying output stream throws an 461 * {@code IOException} other than {@code InterruptedIOException}, 462 * and when the {@code setError} method is invoked. If an operation 463 * on the underlying output stream throws an 464 * {@code InterruptedIOException}, then the {@code PrintStream} 465 * converts the exception back into an interrupt by doing: 466 * <pre>{@code 467 * Thread.currentThread().interrupt(); 468 * }</pre> 469 * or the equivalent. 470 * 471 * @return {@code true} if and only if this stream has encountered an 472 * {@code IOException} other than 473 * {@code InterruptedIOException}, or the 474 * {@code setError} method has been invoked 475 */ 476 public boolean checkError() { 477 if (out != null) 478 flush(); 479 if (out instanceof java.io.PrintStream) { 480 PrintStream ps = (PrintStream) out; 481 return ps.checkError(); 482 } 483 return trouble; 484 } 485 486 /** 487 * Sets the error state of the stream to {@code true}. 488 * 489 * <p> This method will cause subsequent invocations of {@link 490 * #checkError()} to return {@code true} until 491 * {@link #clearError()} is invoked. 492 * 493 * @since 1.1 494 */ 495 protected void setError() { 496 trouble = true; 497 } 498 499 /** 500 * Clears the internal error state of this stream. 501 * 502 * <p> This method will cause subsequent invocations of {@link 503 * #checkError()} to return {@code false} until another write 504 * operation fails and invokes {@link #setError()}. 505 * 506 * @since 1.6 507 */ 508 protected void clearError() { 509 trouble = false; 510 } 511 512 /* 513 * Exception-catching, synchronized output operations, 514 * which also implement the write() methods of OutputStream 515 */ 516 517 /** 518 * Writes the specified byte to this stream. If the byte is a newline and 519 * automatic flushing is enabled then the {@code flush} method will be 520 * invoked. 521 * 522 * <p> Note that the byte is written as given; to write a character that 523 * will be translated according to the platform's default character 524 * encoding, use the {@code print(char)} or {@code println(char)} 525 * methods. 526 * 527 * @param b The byte to be written 528 * @see #print(char) 529 * @see #println(char) 530 */ 531 @Override 532 public void write(int b) { 533 try { 534 synchronized (this) { 535 ensureOpen(); 536 out.write(b); 537 if ((b == '\n') && autoFlush) 538 out.flush(); 539 } 540 } 541 catch (InterruptedIOException x) { 542 Thread.currentThread().interrupt(); 543 } 544 catch (IOException x) { 545 trouble = true; 546 } 547 } 548 549 /** 550 * Writes {@code len} bytes from the specified byte array starting at 551 * offset {@code off} to this stream. If automatic flushing is 552 * enabled then the {@code flush} method will be invoked. 553 * 554 * <p> Note that the bytes will be written as given; to write characters 555 * that will be translated according to the platform's default character 556 * encoding, use the {@code print(char)} or {@code println(char)} 557 * methods. 558 * 559 * @param buf A byte array 560 * @param off Offset from which to start taking bytes 561 * @param len Number of bytes to write 562 */ 563 @Override 564 public void write(byte buf[], int off, int len) { 565 try { 566 synchronized (this) { 567 ensureOpen(); 568 out.write(buf, off, len); 569 if (autoFlush) 570 out.flush(); 571 } 572 } 573 catch (InterruptedIOException x) { 574 Thread.currentThread().interrupt(); 575 } 576 catch (IOException x) { 577 trouble = true; 578 } 579 } 580 581 /** 582 * Writes all bytes from the specified byte array to this stream. If 583 * automatic flushing is enabled then the {@code flush} method will be 584 * invoked. 585 * 586 * <p> Note that the bytes will be written as given; to write characters 587 * that will be translated according to the platform's default character 588 * encoding, use the {@code print(char[])} or {@code println(char[])} 589 * methods. 590 * 591 * @apiNote 592 * Although declared to throw {@code IOException}, this method never 593 * actually does so. Instead, like other methods that this class 594 * overrides, it sets an internal flag which may be tested via the 595 * {@link #checkError()} method. To write an array of bytes without having 596 * to write a {@code catch} block for the {@code IOException}, use either 597 * {@link #writeBytes(byte[] buf) writeBytes(buf)} or 598 * {@link #write(byte[], int, int) write(buf, 0, buf.length)}. 599 * 600 * @implSpec 601 * This method is equivalent to 602 * {@link java.io.PrintStream#write(byte[],int,int) 603 * this.write(buf, 0, buf.length)}. 604 * 605 * @param buf A byte array 606 * 607 * @throws IOException If an I/O error occurs. 608 * 609 * @see #writeBytes(byte[]) 610 * @see #write(byte[],int,int) 611 * 612 * @since 14 613 */ 614 @Override 615 public void write(byte buf[]) throws IOException { 616 this.write(buf, 0, buf.length); 617 } 618 619 /** 620 * Writes all bytes from the specified byte array to this stream. 621 * If automatic flushing is enabled then the {@code flush} method 622 * will be invoked. 623 * 624 * <p> Note that the bytes will be written as given; to write characters 625 * that will be translated according to the platform's default character 626 * encoding, use the {@code print(char[])} or {@code println(char[])} 627 * methods. 628 * 629 * @implSpec 630 * This method is equivalent to 631 * {@link #write(byte[], int, int) this.write(buf, 0, buf.length)}. 632 * 633 * @param buf A byte array 634 * 635 * @since 14 636 */ 637 public void writeBytes(byte buf[]) { 638 this.write(buf, 0, buf.length); 639 } 640 641 /* 642 * The following private methods on the text- and character-output streams 643 * always flush the stream buffers, so that writes to the underlying byte 644 * stream occur as promptly as with the original PrintStream. 645 */ 646 647 private void write(char[] buf) { 648 try { 649 synchronized (this) { 650 ensureOpen(); 651 textOut.write(buf); 652 textOut.flushBuffer(); 653 charOut.flushBuffer(); 654 if (autoFlush) { 655 for (int i = 0; i < buf.length; i++) 656 if (buf[i] == '\n') { 657 out.flush(); 658 break; 659 } 660 } 661 } 662 } catch (InterruptedIOException x) { 663 Thread.currentThread().interrupt(); 664 } catch (IOException x) { 665 trouble = true; 666 } 667 } 668 669 // Used to optimize away back-to-back flushing and synchronization when 670 // using println, but since subclasses could exist which depend on 671 // observing a call to print followed by newLine() we only use this if 672 // getClass() == PrintStream.class to avoid compatibility issues. 673 private void writeln(char[] buf) { 674 try { 675 synchronized (this) { 676 ensureOpen(); 677 textOut.write(buf); 678 textOut.newLine(); 679 textOut.flushBuffer(); 680 charOut.flushBuffer(); 681 if (autoFlush) 682 out.flush(); 683 } 684 } 685 catch (InterruptedIOException x) { 686 Thread.currentThread().interrupt(); 687 } 688 catch (IOException x) { 689 trouble = true; 690 } 691 } 692 693 private void write(String s) { 694 try { 695 synchronized (this) { 696 ensureOpen(); 697 textOut.write(s); 698 textOut.flushBuffer(); 699 charOut.flushBuffer(); 700 if (autoFlush && (s.indexOf('\n') >= 0)) 701 out.flush(); 702 } 703 } 704 catch (InterruptedIOException x) { 705 Thread.currentThread().interrupt(); 706 } 707 catch (IOException x) { 708 trouble = true; 709 } 710 } 711 712 // Used to optimize away back-to-back flushing and synchronization when 713 // using println, but since subclasses could exist which depend on 714 // observing a call to print followed by newLine we only use this if 715 // getClass() == PrintStream.class to avoid compatibility issues. 716 private void writeln(String s) { 717 try { 718 synchronized (this) { 719 ensureOpen(); 720 textOut.write(s); 721 textOut.newLine(); 722 textOut.flushBuffer(); 723 charOut.flushBuffer(); 724 if (autoFlush) 725 out.flush(); 726 } 727 } 728 catch (InterruptedIOException x) { 729 Thread.currentThread().interrupt(); 730 } 731 catch (IOException x) { 732 trouble = true; 733 } 734 } 735 736 private void newLine() { 737 try { 738 synchronized (this) { 739 ensureOpen(); 740 textOut.newLine(); 741 textOut.flushBuffer(); 742 charOut.flushBuffer(); 743 if (autoFlush) 744 out.flush(); 745 } 746 } 747 catch (InterruptedIOException x) { 748 Thread.currentThread().interrupt(); 749 } 750 catch (IOException x) { 751 trouble = true; 752 } 753 } 754 755 /* Methods that do not terminate lines */ 756 757 /** 758 * Prints a boolean value. The string produced by {@link 759 * java.lang.String#valueOf(boolean)} is translated into bytes 760 * according to the platform's default character encoding, and these bytes 761 * are written in exactly the manner of the 762 * {@link #write(int)} method. 763 * 764 * @param b The {@code boolean} to be printed 765 */ 766 public void print(boolean b) { 767 write(String.valueOf(b)); 768 } 769 770 /** 771 * Prints a character. The character is translated into one or more bytes 772 * according to the character encoding given to the constructor, or the 773 * platform's default character encoding if none specified. These bytes 774 * are written in exactly the manner of the {@link #write(int)} method. 775 * 776 * @param c The {@code char} to be printed 777 */ 778 public void print(char c) { 779 write(String.valueOf(c)); 780 } 781 782 /** 783 * Prints an integer. The string produced by {@link 784 * java.lang.String#valueOf(int)} is translated into bytes 785 * according to the platform's default character encoding, and these bytes 786 * are written in exactly the manner of the 787 * {@link #write(int)} method. 788 * 789 * @param i The {@code int} to be printed 790 * @see java.lang.Integer#toString(int) 791 */ 792 public void print(int i) { 793 write(String.valueOf(i)); 794 } 795 796 /** 797 * Prints a long integer. The string produced by {@link 798 * java.lang.String#valueOf(long)} is translated into bytes 799 * according to the platform's default character encoding, and these bytes 800 * are written in exactly the manner of the 801 * {@link #write(int)} method. 802 * 803 * @param l The {@code long} to be printed 804 * @see java.lang.Long#toString(long) 805 */ 806 public void print(long l) { 807 write(String.valueOf(l)); 808 } 809 810 /** 811 * Prints a floating-point number. The string produced by {@link 812 * java.lang.String#valueOf(float)} is translated into bytes 813 * according to the platform's default character encoding, and these bytes 814 * are written in exactly the manner of the 815 * {@link #write(int)} method. 816 * 817 * @param f The {@code float} to be printed 818 * @see java.lang.Float#toString(float) 819 */ 820 public void print(float f) { 821 write(String.valueOf(f)); 822 } 823 824 /** 825 * Prints a double-precision floating-point number. The string produced by 826 * {@link java.lang.String#valueOf(double)} is translated into 827 * bytes according to the platform's default character encoding, and these 828 * bytes are written in exactly the manner of the {@link 829 * #write(int)} method. 830 * 831 * @param d The {@code double} to be printed 832 * @see java.lang.Double#toString(double) 833 */ 834 public void print(double d) { 835 write(String.valueOf(d)); 836 } 837 838 /** 839 * Prints an array of characters. The characters are converted into bytes 840 * according to the character encoding given to the constructor, or the 841 * platform's default character encoding if none specified. These bytes 842 * are written in exactly the manner of the {@link #write(int)} method. 843 * 844 * @param s The array of chars to be printed 845 * 846 * @throws NullPointerException If {@code s} is {@code null} 847 */ 848 public void print(char s[]) { 849 write(s); 850 } 851 852 /** 853 * Prints a string. If the argument is {@code null} then the string 854 * {@code "null"} is printed. Otherwise, the string's characters are 855 * converted into bytes according to the character encoding given to the 856 * constructor, or the platform's default character encoding if none 857 * specified. These bytes are written in exactly the manner of the 858 * {@link #write(int)} method. 859 * 860 * @param s The {@code String} to be printed 861 */ 862 public void print(String s) { 863 write(String.valueOf(s)); 864 } 865 866 /** 867 * Prints an object. The string produced by the {@link 868 * java.lang.String#valueOf(Object)} method is translated into bytes 869 * according to the platform's default character encoding, and these bytes 870 * are written in exactly the manner of the 871 * {@link #write(int)} method. 872 * 873 * @param obj The {@code Object} to be printed 874 * @see java.lang.Object#toString() 875 */ 876 public void print(Object obj) { 877 write(String.valueOf(obj)); 878 } 879 880 881 /* Methods that do terminate lines */ 882 883 /** 884 * Terminates the current line by writing the line separator string. The 885 * line separator string is defined by the system property 886 * {@code line.separator}, and is not necessarily a single newline 887 * character ({@code '\n'}). 888 */ 889 public void println() { 890 newLine(); 891 } 892 893 /** 894 * Prints a boolean and then terminate the line. This method behaves as 895 * though it invokes {@link #print(boolean)} and then 896 * {@link #println()}. 897 * 898 * @param x The {@code boolean} to be printed 899 */ 900 public void println(boolean x) { 901 if (getClass() == PrintStream.class) { 902 writeln(String.valueOf(x)); 903 } else { 904 synchronized (this) { 905 print(x); 906 newLine(); 907 } 908 } 909 } 910 911 /** 912 * Prints a character and then terminate the line. This method behaves as 913 * though it invokes {@link #print(char)} and then 914 * {@link #println()}. 915 * 916 * @param x The {@code char} to be printed. 917 */ 918 public void println(char x) { 919 if (getClass() == PrintStream.class) { 920 writeln(String.valueOf(x)); 921 } else { 922 synchronized (this) { 923 print(x); 924 newLine(); 925 } 926 } 927 } 928 929 /** 930 * Prints an integer and then terminate the line. This method behaves as 931 * though it invokes {@link #print(int)} and then 932 * {@link #println()}. 933 * 934 * @param x The {@code int} to be printed. 935 */ 936 public void println(int x) { 937 if (getClass() == PrintStream.class) { 938 writeln(String.valueOf(x)); 939 } else { 940 synchronized (this) { 941 print(x); 942 newLine(); 943 } 944 } 945 } 946 947 /** 948 * Prints a long and then terminate the line. This method behaves as 949 * though it invokes {@link #print(long)} and then 950 * {@link #println()}. 951 * 952 * @param x a The {@code long} to be printed. 953 */ 954 public void println(long x) { 955 if (getClass() == PrintStream.class) { 956 writeln(String.valueOf(x)); 957 } else { 958 synchronized (this) { 959 print(x); 960 newLine(); 961 } 962 } 963 } 964 965 /** 966 * Prints a float and then terminate the line. This method behaves as 967 * though it invokes {@link #print(float)} and then 968 * {@link #println()}. 969 * 970 * @param x The {@code float} to be printed. 971 */ 972 public void println(float x) { 973 if (getClass() == PrintStream.class) { 974 writeln(String.valueOf(x)); 975 } else { 976 synchronized (this) { 977 print(x); 978 newLine(); 979 } 980 } 981 } 982 983 /** 984 * Prints a double and then terminate the line. This method behaves as 985 * though it invokes {@link #print(double)} and then 986 * {@link #println()}. 987 * 988 * @param x The {@code double} to be printed. 989 */ 990 public void println(double x) { 991 if (getClass() == PrintStream.class) { 992 writeln(String.valueOf(x)); 993 } else { 994 synchronized (this) { 995 print(x); 996 newLine(); 997 } 998 } 999 } 1000 1001 /** 1002 * Prints an array of characters and then terminate the line. This method 1003 * behaves as though it invokes {@link #print(char[])} and 1004 * then {@link #println()}. 1005 * 1006 * @param x an array of chars to print. 1007 */ 1008 public void println(char[] x) { 1009 if (getClass() == PrintStream.class) { 1010 writeln(x); 1011 } else { 1012 synchronized (this) { 1013 print(x); 1014 newLine(); 1015 } 1016 } 1017 } 1018 1019 /** 1020 * Prints a String and then terminate the line. This method behaves as 1021 * though it invokes {@link #print(String)} and then 1022 * {@link #println()}. 1023 * 1024 * @param x The {@code String} to be printed. 1025 */ 1026 public void println(String x) { 1027 if (getClass() == PrintStream.class) { 1028 writeln(String.valueOf(x)); 1029 } else { 1030 synchronized (this) { 1031 print(x); 1032 newLine(); 1033 } 1034 } 1035 } 1036 1037 /** 1038 * Prints an Object and then terminate the line. This method calls 1039 * at first String.valueOf(x) to get the printed object's string value, 1040 * then behaves as 1041 * though it invokes {@link #print(String)} and then 1042 * {@link #println()}. 1043 * 1044 * @param x The {@code Object} to be printed. 1045 */ 1046 public void println(Object x) { 1047 String s = String.valueOf(x); 1048 if (getClass() == PrintStream.class) { 1049 // need to apply String.valueOf again since first invocation 1050 // might return null 1051 writeln(String.valueOf(s)); 1052 } else { 1053 synchronized (this) { 1054 print(s); 1055 newLine(); 1056 } 1057 } 1058 } 1059 1060 1061 /** 1062 * A convenience method to write a formatted string to this output stream 1063 * using the specified format string and arguments. 1064 * 1065 * <p> An invocation of this method of the form 1066 * {@code out.printf(format, args)} behaves 1067 * in exactly the same way as the invocation 1068 * 1069 * <pre>{@code 1070 * out.format(format, args) 1071 * }</pre> 1072 * 1073 * @param format 1074 * A format string as described in <a 1075 * href="../util/Formatter.html#syntax">Format string syntax</a> 1076 * 1077 * @param args 1078 * Arguments referenced by the format specifiers in the format 1079 * string. If there are more arguments than format specifiers, the 1080 * extra arguments are ignored. The number of arguments is 1081 * variable and may be zero. The maximum number of arguments is 1082 * limited by the maximum dimension of a Java array as defined by 1083 * <cite>The Java Virtual Machine Specification</cite>. 1084 * The behaviour on a 1085 * {@code null} argument depends on the <a 1086 * href="../util/Formatter.html#syntax">conversion</a>. 1087 * 1088 * @throws java.util.IllegalFormatException 1089 * If a format string contains an illegal syntax, a format 1090 * specifier that is incompatible with the given arguments, 1091 * insufficient arguments given the format string, or other 1092 * illegal conditions. For specification of all possible 1093 * formatting errors, see the <a 1094 * href="../util/Formatter.html#detail">Details</a> section of the 1095 * formatter class specification. 1096 * 1097 * @throws NullPointerException 1098 * If the {@code format} is {@code null} 1099 * 1100 * @return This output stream 1101 * 1102 * @since 1.5 1103 */ 1104 public PrintStream printf(String format, Object ... args) { 1105 return format(format, args); 1106 } 1107 1108 /** 1109 * A convenience method to write a formatted string to this output stream 1110 * using the specified format string and arguments. 1111 * 1112 * <p> An invocation of this method of the form 1113 * {@code out.printf(l, format, args)} behaves 1114 * in exactly the same way as the invocation 1115 * 1116 * <pre>{@code 1117 * out.format(l, format, args) 1118 * }</pre> 1119 * 1120 * @param l 1121 * The {@linkplain java.util.Locale locale} to apply during 1122 * formatting. If {@code l} is {@code null} then no localization 1123 * is applied. 1124 * 1125 * @param format 1126 * A format string as described in <a 1127 * href="../util/Formatter.html#syntax">Format string syntax</a> 1128 * 1129 * @param args 1130 * Arguments referenced by the format specifiers in the format 1131 * string. If there are more arguments than format specifiers, the 1132 * extra arguments are ignored. The number of arguments is 1133 * variable and may be zero. The maximum number of arguments is 1134 * limited by the maximum dimension of a Java array as defined by 1135 * <cite>The Java Virtual Machine Specification</cite>. 1136 * The behaviour on a 1137 * {@code null} argument depends on the <a 1138 * href="../util/Formatter.html#syntax">conversion</a>. 1139 * 1140 * @throws java.util.IllegalFormatException 1141 * If a format string contains an illegal syntax, a format 1142 * specifier that is incompatible with the given arguments, 1143 * insufficient arguments given the format string, or other 1144 * illegal conditions. For specification of all possible 1145 * formatting errors, see the <a 1146 * href="../util/Formatter.html#detail">Details</a> section of the 1147 * formatter class specification. 1148 * 1149 * @throws NullPointerException 1150 * If the {@code format} is {@code null} 1151 * 1152 * @return This output stream 1153 * 1154 * @since 1.5 1155 */ 1156 public PrintStream printf(Locale l, String format, Object ... args) { 1157 return format(l, format, args); 1158 } 1159 1160 /** 1161 * Writes a formatted string to this output stream using the specified 1162 * format string and arguments. 1163 * 1164 * <p> The locale always used is the one returned by {@link 1165 * java.util.Locale#getDefault(Locale.Category)} with 1166 * {@link java.util.Locale.Category#FORMAT FORMAT} category specified, 1167 * regardless of any previous invocations of other formatting methods on 1168 * this object. 1169 * 1170 * @param format 1171 * A format string as described in <a 1172 * href="../util/Formatter.html#syntax">Format string syntax</a> 1173 * 1174 * @param args 1175 * Arguments referenced by the format specifiers in the format 1176 * string. If there are more arguments than format specifiers, the 1177 * extra arguments are ignored. The number of arguments is 1178 * variable and may be zero. The maximum number of arguments is 1179 * limited by the maximum dimension of a Java array as defined by 1180 * <cite>The Java Virtual Machine Specification</cite>. 1181 * The behaviour on a 1182 * {@code null} argument depends on the <a 1183 * href="../util/Formatter.html#syntax">conversion</a>. 1184 * 1185 * @throws java.util.IllegalFormatException 1186 * If a format string contains an illegal syntax, a format 1187 * specifier that is incompatible with the given arguments, 1188 * insufficient arguments given the format string, or other 1189 * illegal conditions. For specification of all possible 1190 * formatting errors, see the <a 1191 * href="../util/Formatter.html#detail">Details</a> section of the 1192 * formatter class specification. 1193 * 1194 * @throws NullPointerException 1195 * If the {@code format} is {@code null} 1196 * 1197 * @return This output stream 1198 * 1199 * @since 1.5 1200 */ 1201 public PrintStream format(String format, Object ... args) { 1202 try { 1203 synchronized (this) { 1204 ensureOpen(); 1205 if ((formatter == null) 1206 || (formatter.locale() != 1207 Locale.getDefault(Locale.Category.FORMAT))) 1208 formatter = new Formatter((Appendable) this); 1209 formatter.format(Locale.getDefault(Locale.Category.FORMAT), 1210 format, args); 1211 } 1212 } catch (InterruptedIOException x) { 1213 Thread.currentThread().interrupt(); 1214 } catch (IOException x) { 1215 trouble = true; 1216 } 1217 return this; 1218 } 1219 1220 /** 1221 * Writes a formatted string to this output stream using the specified 1222 * format string and arguments. 1223 * 1224 * @param l 1225 * The {@linkplain java.util.Locale locale} to apply during 1226 * formatting. If {@code l} is {@code null} then no localization 1227 * is applied. 1228 * 1229 * @param format 1230 * A format string as described in <a 1231 * href="../util/Formatter.html#syntax">Format string syntax</a> 1232 * 1233 * @param args 1234 * Arguments referenced by the format specifiers in the format 1235 * string. If there are more arguments than format specifiers, the 1236 * extra arguments are ignored. The number of arguments is 1237 * variable and may be zero. The maximum number of arguments is 1238 * limited by the maximum dimension of a Java array as defined by 1239 * <cite>The Java Virtual Machine Specification</cite>. 1240 * The behaviour on a 1241 * {@code null} argument depends on the <a 1242 * href="../util/Formatter.html#syntax">conversion</a>. 1243 * 1244 * @throws java.util.IllegalFormatException 1245 * If a format string contains an illegal syntax, a format 1246 * specifier that is incompatible with the given arguments, 1247 * insufficient arguments given the format string, or other 1248 * illegal conditions. For specification of all possible 1249 * formatting errors, see the <a 1250 * href="../util/Formatter.html#detail">Details</a> section of the 1251 * formatter class specification. 1252 * 1253 * @throws NullPointerException 1254 * If the {@code format} is {@code null} 1255 * 1256 * @return This output stream 1257 * 1258 * @since 1.5 1259 */ 1260 public PrintStream format(Locale l, String format, Object ... args) { 1261 try { 1262 synchronized (this) { 1263 ensureOpen(); 1264 if ((formatter == null) 1265 || (formatter.locale() != l)) 1266 formatter = new Formatter(this, l); 1267 formatter.format(l, format, args); 1268 } 1269 } catch (InterruptedIOException x) { 1270 Thread.currentThread().interrupt(); 1271 } catch (IOException x) { 1272 trouble = true; 1273 } 1274 return this; 1275 } 1276 1277 /** 1278 * Appends the specified character sequence to this output stream. 1279 * 1280 * <p> An invocation of this method of the form {@code out.append(csq)} 1281 * behaves in exactly the same way as the invocation 1282 * 1283 * <pre>{@code 1284 * out.print(csq.toString()) 1285 * }</pre> 1286 * 1287 * <p> Depending on the specification of {@code toString} for the 1288 * character sequence {@code csq}, the entire sequence may not be 1289 * appended. For instance, invoking then {@code toString} method of a 1290 * character buffer will return a subsequence whose content depends upon 1291 * the buffer's position and limit. 1292 * 1293 * @param csq 1294 * The character sequence to append. If {@code csq} is 1295 * {@code null}, then the four characters {@code "null"} are 1296 * appended to this output stream. 1297 * 1298 * @return This output stream 1299 * 1300 * @since 1.5 1301 */ 1302 public PrintStream append(CharSequence csq) { 1303 print(String.valueOf(csq)); 1304 return this; 1305 } 1306 1307 /** 1308 * Appends a subsequence of the specified character sequence to this output 1309 * stream. 1310 * 1311 * <p> An invocation of this method of the form 1312 * {@code out.append(csq, start, end)} when 1313 * {@code csq} is not {@code null}, behaves in 1314 * exactly the same way as the invocation 1315 * 1316 * <pre>{@code 1317 * out.print(csq.subSequence(start, end).toString()) 1318 * }</pre> 1319 * 1320 * @param csq 1321 * The character sequence from which a subsequence will be 1322 * appended. If {@code csq} is {@code null}, then characters 1323 * will be appended as if {@code csq} contained the four 1324 * characters {@code "null"}. 1325 * 1326 * @param start 1327 * The index of the first character in the subsequence 1328 * 1329 * @param end 1330 * The index of the character following the last character in the 1331 * subsequence 1332 * 1333 * @return This output stream 1334 * 1335 * @throws IndexOutOfBoundsException 1336 * If {@code start} or {@code end} are negative, {@code start} 1337 * is greater than {@code end}, or {@code end} is greater than 1338 * {@code csq.length()} 1339 * 1340 * @since 1.5 1341 */ 1342 public PrintStream append(CharSequence csq, int start, int end) { 1343 if (csq == null) csq = "null"; 1344 return append(csq.subSequence(start, end)); 1345 } 1346 1347 /** 1348 * Appends the specified character to this output stream. 1349 * 1350 * <p> An invocation of this method of the form {@code out.append(c)} 1351 * behaves in exactly the same way as the invocation 1352 * 1353 * <pre>{@code 1354 * out.print(c) 1355 * }</pre> 1356 * 1357 * @param c 1358 * The 16-bit character to append 1359 * 1360 * @return This output stream 1361 * 1362 * @since 1.5 1363 */ 1364 public PrintStream append(char c) { 1365 print(c); 1366 return this; 1367 } 1368 1369 }