1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.io; 19 20import java.util.Formatter; 21import java.util.IllegalFormatException; 22import java.util.Locale; 23 24/** 25 * Wraps either an existing {@link OutputStream} or an existing {@link Writer} 26 * and provides convenience methods for printing common data types in a human 27 * readable format. No {@code IOException} is thrown by this class. Instead, 28 * callers should use {@link #checkError()} to see if a problem has occurred in 29 * this writer. 30 */ 31public class PrintWriter extends Writer { 32 /** 33 * The writer to print data to. 34 */ 35 protected Writer out; 36 37 /** 38 * Indicates whether this PrintWriter is in an error state. 39 */ 40 private boolean ioError; 41 42 /** 43 * Indicates whether or not this PrintWriter should flush its contents after 44 * printing a new line. 45 */ 46 private boolean autoFlush; 47 48 /** 49 * Constructs a new {@code PrintWriter} with {@code out} as its target 50 * stream. By default, the new print writer does not automatically flush its 51 * contents to the target stream when a newline is encountered. 52 * 53 * @param out 54 * the target output stream. 55 * @throws NullPointerException 56 * if {@code out} is {@code null}. 57 */ 58 public PrintWriter(OutputStream out) { 59 this(new OutputStreamWriter(out), false); 60 } 61 62 /** 63 * Constructs a new {@code PrintWriter} with {@code out} as its target 64 * stream. The parameter {@code autoFlush} determines if the print writer 65 * automatically flushes its contents to the target stream when a newline is 66 * encountered. 67 * 68 * @param out 69 * the target output stream. 70 * @param autoFlush 71 * indicates whether contents are flushed upon encountering a 72 * newline sequence. 73 * @throws NullPointerException 74 * if {@code out} is {@code null}. 75 */ 76 public PrintWriter(OutputStream out, boolean autoFlush) { 77 this(new OutputStreamWriter(out), autoFlush); 78 } 79 80 /** 81 * Constructs a new {@code PrintWriter} with {@code wr} as its target 82 * writer. By default, the new print writer does not automatically flush its 83 * contents to the target writer when a newline is encountered. 84 * 85 * @param wr 86 * the target writer. 87 * @throws NullPointerException 88 * if {@code wr} is {@code null}. 89 */ 90 public PrintWriter(Writer wr) { 91 this(wr, false); 92 } 93 94 /** 95 * Constructs a new {@code PrintWriter} with {@code out} as its target 96 * writer. The parameter {@code autoFlush} determines if the print writer 97 * automatically flushes its contents to the target writer when a newline is 98 * encountered. 99 * 100 * @param wr 101 * the target writer. 102 * @param autoFlush 103 * indicates whether to flush contents upon encountering a 104 * newline sequence. 105 * @throws NullPointerException 106 * if {@code out} is {@code null}. 107 */ 108 public PrintWriter(Writer wr, boolean autoFlush) { 109 super(wr); 110 this.autoFlush = autoFlush; 111 out = wr; 112 } 113 114 /** 115 * Constructs a new {@code PrintWriter} with {@code file} as its target. The 116 * VM's default character set is used for character encoding. 117 * The print writer does not automatically flush its contents to the target 118 * file when a newline is encountered. The output to the file is buffered. 119 * 120 * @param file 121 * the target file. If the file already exists, its contents are 122 * removed, otherwise a new file is created. 123 * @throws FileNotFoundException 124 * if an error occurs while opening or creating the target file. 125 */ 126 public PrintWriter(File file) throws FileNotFoundException { 127 this(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(file))), false); 128 } 129 130 /** 131 * Constructs a new {@code PrintWriter} with {@code file} as its target. The 132 * character set named {@code csn} is used for character encoding. 133 * The print writer does not automatically flush its contents to the target 134 * file when a newline is encountered. The output to the file is buffered. 135 * 136 * @param file 137 * the target file. If the file already exists, its contents are 138 * removed, otherwise a new file is created. 139 * @param csn 140 * the name of the character set used for character encoding. 141 * @throws FileNotFoundException 142 * if an error occurs while opening or creating the target file. 143 * @throws NullPointerException 144 * if {@code csn} is {@code null}. 145 * @throws UnsupportedEncodingException 146 * if the encoding specified by {@code csn} is not supported. 147 */ 148 public PrintWriter(File file, String csn) throws FileNotFoundException, 149 UnsupportedEncodingException { 150 this(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(file)), csn), 151 false); 152 } 153 154 /** 155 * Constructs a new {@code PrintWriter} with the file identified by {@code 156 * fileName} as its target. The VM's default character set is 157 * used for character encoding. The print writer does not automatically 158 * flush its contents to the target file when a newline is encountered. The 159 * output to the file is buffered. 160 * 161 * @param fileName 162 * the target file's name. If the file already exists, its 163 * contents are removed, otherwise a new file is created. 164 * @throws FileNotFoundException 165 * if an error occurs while opening or creating the target file. 166 */ 167 public PrintWriter(String fileName) throws FileNotFoundException { 168 this(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(fileName))), 169 false); 170 } 171 172 /** 173 * Constructs a new {@code PrintWriter} with the file identified by {@code 174 * fileName} as its target. The character set named {@code csn} is used for 175 * character encoding. The print writer does not automatically flush its 176 * contents to the target file when a newline is encountered. The output to 177 * the file is buffered. 178 * 179 * @param fileName 180 * the target file's name. If the file already exists, its 181 * contents are removed, otherwise a new file is created. 182 * @param csn 183 * the name of the character set used for character encoding. 184 * @throws FileNotFoundException 185 * if an error occurs while opening or creating the target file. 186 * @throws NullPointerException 187 * if {@code csn} is {@code null}. 188 * @throws UnsupportedEncodingException 189 * if the encoding specified by {@code csn} is not supported. 190 */ 191 public PrintWriter(String fileName, String csn) 192 throws FileNotFoundException, UnsupportedEncodingException { 193 this(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(fileName)), csn), 194 false); 195 } 196 197 /** 198 * Flushes this writer and returns the value of the error flag. 199 * 200 * @return {@code true} if either an {@code IOException} has been thrown 201 * previously or if {@code setError()} has been called; 202 * {@code false} otherwise. 203 * @see #setError() 204 */ 205 public boolean checkError() { 206 Writer delegate = out; 207 if (delegate == null) { 208 return ioError; 209 } 210 211 flush(); 212 return ioError || delegate.checkError(); 213 } 214 215 /** 216 * Sets the error state of the stream to false. 217 * @since 1.6 218 */ 219 protected void clearError() { 220 synchronized (lock) { 221 ioError = false; 222 } 223 } 224 225 /** 226 * Closes this print writer. Flushes this writer and then closes the target. 227 * If an I/O error occurs, this writer's error flag is set to {@code true}. 228 */ 229 @Override 230 public void close() { 231 synchronized (lock) { 232 if (out != null) { 233 try { 234 out.close(); 235 } catch (IOException e) { 236 setError(); 237 } 238 out = null; 239 } 240 } 241 } 242 243 /** 244 * Ensures that all pending data is sent out to the target. It also 245 * flushes the target. If an I/O error occurs, this writer's error 246 * state is set to {@code true}. 247 */ 248 @Override 249 public void flush() { 250 synchronized (lock) { 251 if (out != null) { 252 try { 253 out.flush(); 254 } catch (IOException e) { 255 setError(); 256 } 257 } else { 258 setError(); 259 } 260 } 261 } 262 263 /** 264 * Formats {@code args} according to the format string {@code format}, and writes the result 265 * to this stream. This method uses the user's default locale. 266 * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>". 267 * If automatic flushing is enabled then the buffer is flushed as well. 268 * 269 * @param format the format string (see {@link java.util.Formatter#format}) 270 * @param args 271 * the list of arguments passed to the formatter. If there are 272 * more arguments than required by {@code format}, 273 * additional arguments are ignored. 274 * @return this writer. 275 * @throws IllegalFormatException 276 * if the format string is illegal or incompatible with the 277 * arguments, if there are not enough arguments or if any other 278 * error regarding the format string or arguments is detected. 279 * @throws NullPointerException if {@code format == null} 280 */ 281 public PrintWriter format(String format, Object... args) { 282 return format(Locale.getDefault(), format, args); 283 } 284 285 /** 286 * Writes a string formatted by an intermediate {@code Formatter} to the 287 * target using the specified locale, format string and arguments. If 288 * automatic flushing is enabled then this writer is flushed. 289 * 290 * @param l 291 * the locale used in the method. No localization will be applied 292 * if {@code l} is {@code null}. 293 * @param format the format string (see {@link java.util.Formatter#format}) 294 * @param args 295 * the list of arguments passed to the formatter. If there are 296 * more arguments than required by {@code format}, 297 * additional arguments are ignored. 298 * @return this writer. 299 * @throws IllegalFormatException 300 * if the format string is illegal or incompatible with the 301 * arguments, if there are not enough arguments or if any other 302 * error regarding the format string or arguments is detected. 303 * @throws NullPointerException if {@code format == null} 304 */ 305 public PrintWriter format(Locale l, String format, Object... args) { 306 if (format == null) { 307 throw new NullPointerException("format == null"); 308 } 309 new Formatter(this, l).format(format, args); 310 if (autoFlush) { 311 flush(); 312 } 313 return this; 314 } 315 316 /** 317 * Prints a formatted string. The behavior of this method is the same as 318 * this writer's {@code #format(String, Object...)} method. 319 * 320 * <p>The {@code Locale} used is the user's default locale. 321 * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>". 322 * 323 * @param format the format string (see {@link java.util.Formatter#format}) 324 * @param args 325 * the list of arguments passed to the formatter. If there are 326 * more arguments than required by {@code format}, 327 * additional arguments are ignored. 328 * @return this writer. 329 * @throws IllegalFormatException 330 * if the format string is illegal or incompatible with the 331 * arguments, if there are not enough arguments or if any other 332 * error regarding the format string or arguments is detected. 333 * @throws NullPointerException if {@code format == null} 334 */ 335 public PrintWriter printf(String format, Object... args) { 336 return format(format, args); 337 } 338 339 /** 340 * Prints a formatted string. The behavior of this method is the same as 341 * this writer's {@code #format(Locale, String, Object...)} method. 342 * 343 * @param l 344 * the locale used in the method. No localization will be applied 345 * if {@code l} is {@code null}. 346 * @param format the format string (see {@link java.util.Formatter#format}) 347 * @param args 348 * the list of arguments passed to the formatter. If there are 349 * more arguments than required by {@code format}, 350 * additional arguments are ignored. 351 * @return this writer. 352 * @throws IllegalFormatException 353 * if the format string is illegal or incompatible with the 354 * arguments, if there are not enough arguments or if any other 355 * error regarding the format string or arguments is detected. 356 * @throws NullPointerException if {@code format == null} 357 */ 358 public PrintWriter printf(Locale l, String format, Object... args) { 359 return format(l, format, args); 360 } 361 362 /** 363 * Prints the string representation of the specified character array 364 * to the target. 365 * 366 * @param charArray 367 * the character array to print to the target. 368 * @see #print(String) 369 */ 370 public void print(char[] charArray) { 371 print(new String(charArray, 0, charArray.length)); 372 } 373 374 /** 375 * Prints the string representation of the specified character to the 376 * target. 377 * 378 * @param ch 379 * the character to print to the target. 380 * @see #print(String) 381 */ 382 public void print(char ch) { 383 print(String.valueOf(ch)); 384 } 385 386 /** 387 * Prints the string representation of the specified double to the target. 388 * 389 * @param dnum 390 * the double value to print to the target. 391 * @see #print(String) 392 */ 393 public void print(double dnum) { 394 print(String.valueOf(dnum)); 395 } 396 397 /** 398 * Prints the string representation of the specified float to the target. 399 * 400 * @param fnum 401 * the float value to print to the target. 402 * @see #print(String) 403 */ 404 public void print(float fnum) { 405 print(String.valueOf(fnum)); 406 } 407 408 /** 409 * Prints the string representation of the specified integer to the target. 410 * 411 * @param inum 412 * the integer value to print to the target. 413 * @see #print(String) 414 */ 415 public void print(int inum) { 416 print(String.valueOf(inum)); 417 } 418 419 /** 420 * Prints the string representation of the specified long to the target. 421 * 422 * @param lnum 423 * the long value to print to the target. 424 * @see #print(String) 425 */ 426 public void print(long lnum) { 427 print(String.valueOf(lnum)); 428 } 429 430 /** 431 * Prints the string representation of the specified object to the target. 432 * 433 * @param obj 434 * the object to print to the target. 435 * @see #print(String) 436 */ 437 public void print(Object obj) { 438 print(String.valueOf(obj)); 439 } 440 441 /** 442 * Prints a string to the target. The string is converted to an array of 443 * bytes using the encoding chosen during the construction of this writer. 444 * The bytes are then written to the target with {@code write(int)}. 445 * <p> 446 * If an I/O error occurs, this writer's error flag is set to {@code true}. 447 * 448 * @param str 449 * the string to print to the target. 450 * @see #write(int) 451 */ 452 public void print(String str) { 453 write(str != null ? str : String.valueOf((Object) null)); 454 } 455 456 /** 457 * Prints the string representation of the specified boolean to the target. 458 * 459 * @param bool 460 * the boolean value to print the target. 461 * @see #print(String) 462 */ 463 public void print(boolean bool) { 464 print(String.valueOf(bool)); 465 } 466 467 /** 468 * Prints a newline. Flushes this writer if the autoFlush flag is set to {@code true}. 469 */ 470 public void println() { 471 synchronized (lock) { 472 print(System.lineSeparator()); 473 if (autoFlush) { 474 flush(); 475 } 476 } 477 } 478 479 /** 480 * Prints the string representation of the character array {@code chars} followed by a newline. 481 * Flushes this writer if the autoFlush flag is set to {@code true}. 482 */ 483 public void println(char[] chars) { 484 println(new String(chars, 0, chars.length)); 485 } 486 487 /** 488 * Prints the string representation of the char {@code c} followed by a newline. 489 * Flushes this writer if the autoFlush flag is set to {@code true}. 490 */ 491 public void println(char c) { 492 println(String.valueOf(c)); 493 } 494 495 /** 496 * Prints the string representation of the double {@code d} followed by a newline. 497 * Flushes this writer if the autoFlush flag is set to {@code true}. 498 */ 499 public void println(double d) { 500 println(String.valueOf(d)); 501 } 502 503 /** 504 * Prints the string representation of the float {@code f} followed by a newline. 505 * Flushes this writer if the autoFlush flag is set to {@code true}. 506 */ 507 public void println(float f) { 508 println(String.valueOf(f)); 509 } 510 511 /** 512 * Prints the string representation of the int {@code i} followed by a newline. 513 * Flushes this writer if the autoFlush flag is set to {@code true}. 514 */ 515 public void println(int i) { 516 println(String.valueOf(i)); 517 } 518 519 /** 520 * Prints the string representation of the long {@code l} followed by a newline. 521 * Flushes this writer if the autoFlush flag is set to {@code true}. 522 */ 523 public void println(long l) { 524 println(String.valueOf(l)); 525 } 526 527 /** 528 * Prints the string representation of the object {@code o}, or {@code "null}, 529 * followed by a newline. 530 * Flushes this writer if the autoFlush flag is set to {@code true}. 531 */ 532 public void println(Object obj) { 533 println(String.valueOf(obj)); 534 } 535 536 /** 537 * Prints the string representation of the string {@code s} followed by a newline. 538 * Flushes this writer if the autoFlush flag is set to {@code true}. 539 * 540 * <p>The string is converted to an array of bytes using the 541 * encoding chosen during the construction of this writer. The bytes are 542 * then written to the target with {@code write(int)}. Finally, this writer 543 * is flushed if the autoFlush flag is set to {@code true}. 544 * 545 * <p>If an I/O error occurs, this writer's error flag is set to {@code true}. 546 */ 547 public void println(String str) { 548 synchronized (lock) { 549 print(str); 550 println(); 551 } 552 } 553 554 /** 555 * Prints the string representation of the boolean {@code b} followed by a newline. 556 * Flushes this writer if the autoFlush flag is set to {@code true}. 557 */ 558 public void println(boolean b) { 559 println(String.valueOf(b)); 560 } 561 562 /** 563 * Sets the error flag of this writer to true. 564 */ 565 protected void setError() { 566 synchronized (lock) { 567 ioError = true; 568 } 569 } 570 571 /** 572 * Writes the character buffer {@code buf} to the target. 573 * 574 * @param buf 575 * the non-null array containing characters to write. 576 */ 577 @Override 578 public void write(char[] buf) { 579 write(buf, 0, buf.length); 580 } 581 582 /** 583 * Writes {@code count} characters from {@code buffer} starting at {@code 584 * offset} to the target. 585 * <p> 586 * This writer's error flag is set to {@code true} if this writer is closed 587 * or an I/O error occurs. 588 * 589 * @param buf 590 * the buffer to write to the target. 591 * @param offset 592 * the index of the first character in {@code buffer} to write. 593 * @param count 594 * the number of characters in {@code buffer} to write. 595 * @throws IndexOutOfBoundsException 596 * if {@code offset < 0} or {@code count < 0}, or if {@code 597 * offset + count} is greater than the length of {@code buf}. 598 */ 599 @Override 600 public void write(char[] buf, int offset, int count) { 601 doWrite(buf, offset, count); 602 } 603 604 /** 605 * Writes one character to the target. Only the two least significant bytes 606 * of the integer {@code oneChar} are written. 607 * <p> 608 * This writer's error flag is set to {@code true} if this writer is closed 609 * or an I/O error occurs. 610 * 611 * @param oneChar 612 * the character to write to the target. 613 */ 614 @Override 615 public void write(int oneChar) { 616 doWrite(new char[] { (char) oneChar }, 0, 1); 617 } 618 619 private final void doWrite(char[] buf, int offset, int count) { 620 synchronized (lock) { 621 if (out != null) { 622 try { 623 out.write(buf, offset, count); 624 } catch (IOException e) { 625 setError(); 626 } 627 } else { 628 setError(); 629 } 630 } 631 } 632 633 /** 634 * Writes the characters from the specified string to the target. 635 * 636 * @param str 637 * the non-null string containing the characters to write. 638 */ 639 @Override 640 public void write(String str) { 641 write(str.toCharArray()); 642 } 643 644 /** 645 * Writes {@code count} characters from {@code str} starting at {@code 646 * offset} to the target. 647 * 648 * @param str 649 * the non-null string containing the characters to write. 650 * @param offset 651 * the index of the first character in {@code str} to write. 652 * @param count 653 * the number of characters from {@code str} to write. 654 * @throws IndexOutOfBoundsException 655 * if {@code offset < 0} or {@code count < 0}, or if {@code 656 * offset + count} is greater than the length of {@code str}. 657 */ 658 @Override 659 public void write(String str, int offset, int count) { 660 write(str.substring(offset, offset + count).toCharArray()); 661 } 662 663 /** 664 * Appends the character {@code c} to the target. 665 * 666 * @param c 667 * the character to append to the target. 668 * @return this writer. 669 */ 670 @Override 671 public PrintWriter append(char c) { 672 write(c); 673 return this; 674 } 675 676 /** 677 * Appends the character sequence {@code csq} to the target. This 678 * method works the same way as {@code PrintWriter.print(csq.toString())}. 679 * If {@code csq} is {@code null}, then the string "null" is written 680 * to the target. 681 * 682 * @param csq 683 * the character sequence appended to the target. 684 * @return this writer. 685 */ 686 @Override 687 public PrintWriter append(CharSequence csq) { 688 if (csq == null) { 689 csq = "null"; 690 } 691 append(csq, 0, csq.length()); 692 return this; 693 } 694 695 /** 696 * Appends a subsequence of the character sequence {@code csq} to the 697 * target. This method works the same way as {@code 698 * PrintWriter.print(csq.subsequence(start, end).toString())}. If {@code 699 * csq} is {@code null}, then the specified subsequence of the string "null" 700 * will be written to the target. 701 * 702 * @param csq 703 * the character sequence appended to the target. 704 * @param start 705 * the index of the first char in the character sequence appended 706 * to the target. 707 * @param end 708 * the index of the character following the last character of the 709 * subsequence appended to the target. 710 * @return this writer. 711 * @throws StringIndexOutOfBoundsException 712 * if {@code start > end}, {@code start < 0}, {@code end < 0} or 713 * either {@code start} or {@code end} are greater or equal than 714 * the length of {@code csq}. 715 */ 716 @Override 717 public PrintWriter append(CharSequence csq, int start, int end) { 718 if (csq == null) { 719 csq = "null"; 720 } 721 String output = csq.subSequence(start, end).toString(); 722 write(output, 0, output.length()); 723 return this; 724 } 725} 726