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