001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.io; 018 019import java.io.BufferedInputStream; 020import java.io.BufferedOutputStream; 021import java.io.BufferedReader; 022import java.io.BufferedWriter; 023import java.io.ByteArrayInputStream; 024import java.io.CharArrayWriter; 025import java.io.Closeable; 026import java.io.EOFException; 027import java.io.File; 028import java.io.IOException; 029import java.io.InputStream; 030import java.io.InputStreamReader; 031import java.io.OutputStream; 032import java.io.OutputStreamWriter; 033import java.io.PrintWriter; 034import java.io.Reader; 035import java.io.Writer; 036import java.net.HttpURLConnection; 037import java.net.ServerSocket; 038import java.net.Socket; 039import java.net.URI; 040import java.net.URL; 041import java.net.URLConnection; 042import java.nio.ByteBuffer; 043import java.nio.CharBuffer; 044import java.nio.channels.ReadableByteChannel; 045import java.nio.channels.Selector; 046import java.nio.charset.Charset; 047import java.util.ArrayList; 048import java.util.Collection; 049import java.util.List; 050import java.util.Objects; 051import java.util.function.Consumer; 052 053import org.apache.commons.io.function.IOConsumer; 054import org.apache.commons.io.output.AppendableWriter; 055import org.apache.commons.io.output.ByteArrayOutputStream; 056import org.apache.commons.io.output.StringBuilderWriter; 057 058/** 059 * General IO stream manipulation utilities. 060 * <p> 061 * This class provides static utility methods for input/output operations. 062 * <ul> 063 * <li><b>[Deprecated]</b> closeQuietly - these methods close a stream ignoring nulls and exceptions 064 * <li>toXxx/read - these methods read data from a stream 065 * <li>write - these methods write data to a stream 066 * <li>copy - these methods copy all the data from one stream to another 067 * <li>contentEquals - these methods compare the content of two streams 068 * </ul> 069 * <p> 070 * The byte-to-char methods and char-to-byte methods involve a conversion step. 071 * Two methods are provided in each case, one that uses the platform default 072 * encoding and the other which allows you to specify an encoding. You are 073 * encouraged to always specify an encoding because relying on the platform 074 * default can lead to unexpected results, for example when moving from 075 * development to production. 076 * <p> 077 * All the methods in this class that read a stream are buffered internally. 078 * This means that there is no cause to use a <code>BufferedInputStream</code> 079 * or <code>BufferedReader</code>. The default buffer size of 4K has been shown 080 * to be efficient in tests. 081 * <p> 082 * The various copy methods all delegate the actual copying to one of the following methods: 083 * <ul> 084 * <li>{@link #copyLarge(InputStream, OutputStream, byte[])}</li> 085 * <li>{@link #copyLarge(InputStream, OutputStream, long, long, byte[])}</li> 086 * <li>{@link #copyLarge(Reader, Writer, char[])}</li> 087 * <li>{@link #copyLarge(Reader, Writer, long, long, char[])}</li> 088 * </ul> 089 * For example, {@link #copy(InputStream, OutputStream)} calls {@link #copyLarge(InputStream, OutputStream)} 090 * which calls {@link #copy(InputStream, OutputStream, int)} which creates the buffer and calls 091 * {@link #copyLarge(InputStream, OutputStream, byte[])}. 092 * <p> 093 * Applications can re-use buffers by using the underlying methods directly. 094 * This may improve performance for applications that need to do a lot of copying. 095 * <p> 096 * Wherever possible, the methods in this class do <em>not</em> flush or close 097 * the stream. This is to avoid making non-portable assumptions about the 098 * streams' origin and further use. Thus the caller is still responsible for 099 * closing streams after use. 100 * <p> 101 * Origin of code: Excalibur. 102 */ 103public class IOUtils { 104 // NOTE: This class is focused on InputStream, OutputStream, Reader and 105 // Writer. Each method should take at least one of these as a parameter, 106 // or return one of them. 107 108 private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; 109 110 /** 111 * The default buffer size ({@value}) to use in copy methods. 112 */ 113 public static final int DEFAULT_BUFFER_SIZE = 8192; 114 115 /** 116 * The system directory separator character. 117 */ 118 public static final char DIR_SEPARATOR = File.separatorChar; 119 120 /** 121 * The Unix directory separator character. 122 */ 123 public static final char DIR_SEPARATOR_UNIX = '/'; 124 125 /** 126 * The Windows directory separator character. 127 */ 128 public static final char DIR_SEPARATOR_WINDOWS = '\\'; 129 130 /** 131 * Represents the end-of-file (or stream). 132 * @since 2.5 (made public) 133 */ 134 public static final int EOF = -1; 135 136 /** 137 * The system line separator string. 138 */ 139 public static final String LINE_SEPARATOR; 140 141 /** 142 * The Unix line separator string. 143 */ 144 public static final String LINE_SEPARATOR_UNIX = "\n"; 145 146 /** 147 * The Windows line separator string. 148 */ 149 public static final String LINE_SEPARATOR_WINDOWS = "\r\n"; 150 151 /** 152 * The default buffer size to use for the skip() methods. 153 */ 154 private static final int SKIP_BUFFER_SIZE = 2048; 155 156 private static byte[] SKIP_BYTE_BUFFER; 157 158 // Allocated in the relevant skip method if necessary. 159 /* 160 * These buffers are static and are shared between threads. 161 * This is possible because the buffers are write-only - the contents are never read. 162 * 163 * N.B. there is no need to synchronize when creating these because: 164 * - we don't care if the buffer is created multiple times (the data is ignored) 165 * - we always use the same size buffer, so if it it is recreated it will still be OK 166 * (if the buffer size were variable, we would need to synch. to ensure some other thread 167 * did not create a smaller one) 168 */ 169 private static char[] SKIP_CHAR_BUFFER; 170 171 static { 172 // avoid security issues 173 try (final StringBuilderWriter buf = new StringBuilderWriter(4); 174 final PrintWriter out = new PrintWriter(buf)) { 175 out.println(); 176 LINE_SEPARATOR = buf.toString(); 177 } 178 } 179 180 /** 181 * Returns the given InputStream if it is already a {@link BufferedInputStream}, otherwise creates a 182 * BufferedInputStream from the given InputStream. 183 * 184 * @param inputStream the InputStream to wrap or return (not null) 185 * @return the given InputStream or a new {@link BufferedInputStream} for the given InputStream 186 * @throws NullPointerException if the input parameter is null 187 * @since 2.5 188 */ 189 public static BufferedInputStream buffer(final InputStream inputStream) { 190 // reject null early on rather than waiting for IO operation to fail 191 // not checked by BufferedInputStream 192 Objects.requireNonNull(inputStream, "inputStream"); 193 return inputStream instanceof BufferedInputStream ? 194 (BufferedInputStream) inputStream : new BufferedInputStream(inputStream); 195 } 196 197 /** 198 * Returns the given InputStream if it is already a {@link BufferedInputStream}, otherwise creates a 199 * BufferedInputStream from the given InputStream. 200 * 201 * @param inputStream the InputStream to wrap or return (not null) 202 * @param size the buffer size, if a new BufferedInputStream is created. 203 * @return the given InputStream or a new {@link BufferedInputStream} for the given InputStream 204 * @throws NullPointerException if the input parameter is null 205 * @since 2.5 206 */ 207 public static BufferedInputStream buffer(final InputStream inputStream, final int size) { 208 // reject null early on rather than waiting for IO operation to fail 209 // not checked by BufferedInputStream 210 Objects.requireNonNull(inputStream, "inputStream"); 211 return inputStream instanceof BufferedInputStream ? 212 (BufferedInputStream) inputStream : new BufferedInputStream(inputStream, size); 213 } 214 215 /** 216 * Returns the given OutputStream if it is already a {@link BufferedOutputStream}, otherwise creates a 217 * BufferedOutputStream from the given OutputStream. 218 * 219 * @param outputStream the OutputStream to wrap or return (not null) 220 * @return the given OutputStream or a new {@link BufferedOutputStream} for the given OutputStream 221 * @throws NullPointerException if the input parameter is null 222 * @since 2.5 223 */ 224 public static BufferedOutputStream buffer(final OutputStream outputStream) { 225 // reject null early on rather than waiting for IO operation to fail 226 // not checked by BufferedInputStream 227 Objects.requireNonNull(outputStream, "outputStream"); 228 return outputStream instanceof BufferedOutputStream ? 229 (BufferedOutputStream) outputStream : new BufferedOutputStream(outputStream); 230 } 231 232 /** 233 * Returns the given OutputStream if it is already a {@link BufferedOutputStream}, otherwise creates a 234 * BufferedOutputStream from the given OutputStream. 235 * 236 * @param outputStream the OutputStream to wrap or return (not null) 237 * @param size the buffer size, if a new BufferedOutputStream is created. 238 * @return the given OutputStream or a new {@link BufferedOutputStream} for the given OutputStream 239 * @throws NullPointerException if the input parameter is null 240 * @since 2.5 241 */ 242 public static BufferedOutputStream buffer(final OutputStream outputStream, final int size) { 243 // reject null early on rather than waiting for IO operation to fail 244 // not checked by BufferedInputStream 245 Objects.requireNonNull(outputStream, "outputStream"); 246 return outputStream instanceof BufferedOutputStream ? 247 (BufferedOutputStream) outputStream : new BufferedOutputStream(outputStream, size); 248 } 249 250 /** 251 * Returns the given reader if it is already a {@link BufferedReader}, otherwise creates a BufferedReader from 252 * the given reader. 253 * 254 * @param reader the reader to wrap or return (not null) 255 * @return the given reader or a new {@link BufferedReader} for the given reader 256 * @throws NullPointerException if the input parameter is null 257 * @since 2.5 258 */ 259 public static BufferedReader buffer(final Reader reader) { 260 return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader); 261 } 262 263 /** 264 * Returns the given reader if it is already a {@link BufferedReader}, otherwise creates a BufferedReader from the 265 * given reader. 266 * 267 * @param reader the reader to wrap or return (not null) 268 * @param size the buffer size, if a new BufferedReader is created. 269 * @return the given reader or a new {@link BufferedReader} for the given reader 270 * @throws NullPointerException if the input parameter is null 271 * @since 2.5 272 */ 273 public static BufferedReader buffer(final Reader reader, final int size) { 274 return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader, size); 275 } 276 277 /** 278 * Returns the given Writer if it is already a {@link BufferedWriter}, otherwise creates a BufferedWriter from the 279 * given Writer. 280 * 281 * @param writer the Writer to wrap or return (not null) 282 * @return the given Writer or a new {@link BufferedWriter} for the given Writer 283 * @throws NullPointerException if the input parameter is null 284 * @since 2.5 285 */ 286 public static BufferedWriter buffer(final Writer writer) { 287 return writer instanceof BufferedWriter ? (BufferedWriter) writer : new BufferedWriter(writer); 288 } 289 290 /** 291 * Returns the given Writer if it is already a {@link BufferedWriter}, otherwise creates a BufferedWriter from the 292 * given Writer. 293 * 294 * @param writer the Writer to wrap or return (not null) 295 * @param size the buffer size, if a new BufferedWriter is created. 296 * @return the given Writer or a new {@link BufferedWriter} for the given Writer 297 * @throws NullPointerException if the input parameter is null 298 * @since 2.5 299 */ 300 public static BufferedWriter buffer(final Writer writer, final int size) { 301 return writer instanceof BufferedWriter ? (BufferedWriter) writer : new BufferedWriter(writer, size); 302 } 303 304 /** 305 * Closes a <code>Closeable</code> unconditionally. 306 * <p> 307 * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored. This is typically used in 308 * finally blocks. 309 * <p> 310 * Example code: 311 * </p> 312 * <pre> 313 * Closeable closeable = null; 314 * try { 315 * closeable = new FileReader("foo.txt"); 316 * // process closeable 317 * closeable.close(); 318 * } catch (Exception e) { 319 * // error handling 320 * } finally { 321 * IOUtils.closeQuietly(closeable); 322 * } 323 * </pre> 324 * <p> 325 * Closing all streams: 326 * </p> 327 * <pre> 328 * try { 329 * return IOUtils.copy(inputStream, outputStream); 330 * } finally { 331 * IOUtils.closeQuietly(inputStream); 332 * IOUtils.closeQuietly(outputStream); 333 * } 334 * </pre> 335 * 336 * @param closeable the objects to close, may be null or already closed 337 * @since 2.0 338 * 339 * @deprecated As of 2.6 deprecated without replacement. Please use the try-with-resources statement or handle 340 * suppressed exceptions manually. 341 * @see Throwable#addSuppressed(java.lang.Throwable) 342 */ 343 @Deprecated 344 public static void closeQuietly(final Closeable closeable) { 345 closeQuietly(closeable, (Consumer<IOException>) null); 346 } 347 348 /** 349 * Closes the given {@link Closeable} as a null-safe operation while consuming IOException by the given {@code consumer}. 350 * 351 * @param closeable The resource to close, may be null. 352 * @param consumer Consumes the IOException thrown by {@link Closeable#close()}. 353 * @since 2.7 354 */ 355 public static void closeQuietly(final Closeable closeable, final Consumer<IOException> consumer) { 356 if (closeable != null) { 357 try { 358 closeable.close(); 359 } catch (IOException e) { 360 if (consumer != null) { 361 consumer.accept(e); 362 } 363 } 364 } 365 } 366 367 /** 368 * Closes the given {@link Closeable} as a null-safe operation. 369 * 370 * @param closeable The resource to close, may be null. 371 * @throws IOException if an I/O error occurs. 372 * @since 2.7 373 */ 374 public static void close(final Closeable closeable) throws IOException { 375 if (closeable != null) { 376 closeable.close(); 377 } 378 } 379 380 /** 381 * Closes the given {@link Closeable} as a null-safe operation. 382 * 383 * @param closeable The resource to close, may be null. 384 * @param consumer Consume the IOException thrown by {@link Closeable#close()}. 385 * @throws IOException if an I/O error occurs. 386 * @since 2.7 387 */ 388 public static void close(final Closeable closeable, final IOConsumer<IOException> consumer) throws IOException { 389 if (closeable != null) { 390 try { 391 closeable.close(); 392 } catch (IOException e) { 393 if (consumer != null) { 394 consumer.accept(e); 395 } 396 } 397 } 398 } 399 400 /** 401 * Closes a URLConnection. 402 * 403 * @param conn the connection to close. 404 * @since 2.4 405 */ 406 public static void close(final URLConnection conn) { 407 if (conn instanceof HttpURLConnection) { 408 ((HttpURLConnection) conn).disconnect(); 409 } 410 } 411 412 /** 413 * Closes a <code>Closeable</code> unconditionally. 414 * <p> 415 * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored. 416 * <p> 417 * This is typically used in finally blocks to ensure that the closeable is closed 418 * even if an Exception was thrown before the normal close statement was reached. 419 * <br> 420 * <b>It should not be used to replace the close statement(s) 421 * which should be present for the non-exceptional case.</b> 422 * <br> 423 * It is only intended to simplify tidying up where normal processing has already failed 424 * and reporting close failure as well is not necessary or useful. 425 * <p> 426 * Example code: 427 * </p> 428 * <pre> 429 * Closeable closeable = null; 430 * try { 431 * closeable = new FileReader("foo.txt"); 432 * // processing using the closeable; may throw an Exception 433 * closeable.close(); // Normal close - exceptions not ignored 434 * } catch (Exception e) { 435 * // error handling 436 * } finally { 437 * <b>IOUtils.closeQuietly(closeable); // In case normal close was skipped due to Exception</b> 438 * } 439 * </pre> 440 * <p> 441 * Closing all streams: 442 * <br> 443 * <pre> 444 * try { 445 * return IOUtils.copy(inputStream, outputStream); 446 * } finally { 447 * IOUtils.closeQuietly(inputStream, outputStream); 448 * } 449 * </pre> 450 * 451 * @param closeables the objects to close, may be null or already closed 452 * @see #closeQuietly(Closeable) 453 * @since 2.5 454 * 455 * @deprecated As of 2.6 deprecated without replacement. Please use the try-with-resources statement or handle 456 * suppressed exceptions manually. 457 * @see Throwable#addSuppressed(java.lang.Throwable) 458 */ 459 @Deprecated 460 public static void closeQuietly(final Closeable... closeables) { 461 if (closeables == null) { 462 return; 463 } 464 for (final Closeable closeable : closeables) { 465 closeQuietly(closeable); 466 } 467 } 468 469 /** 470 * Closes an <code>InputStream</code> unconditionally. 471 * <p> 472 * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored. 473 * This is typically used in finally blocks. 474 * <p> 475 * Example code: 476 * <pre> 477 * byte[] data = new byte[1024]; 478 * InputStream in = null; 479 * try { 480 * in = new FileInputStream("foo.txt"); 481 * in.read(data); 482 * in.close(); //close errors are handled 483 * } catch (Exception e) { 484 * // error handling 485 * } finally { 486 * IOUtils.closeQuietly(in); 487 * } 488 * </pre> 489 * 490 * @param input the InputStream to close, may be null or already closed 491 * 492 * @deprecated As of 2.6 deprecated without replacement. Please use the try-with-resources statement or handle 493 * suppressed exceptions manually. 494 * @see Throwable#addSuppressed(java.lang.Throwable) 495 */ 496 @Deprecated 497 public static void closeQuietly(final InputStream input) { 498 closeQuietly((Closeable) input); 499 } 500 501 /** 502 * Closes an <code>OutputStream</code> unconditionally. 503 * <p> 504 * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored. 505 * This is typically used in finally blocks. 506 * <p> 507 * Example code: 508 * <pre> 509 * byte[] data = "Hello, World".getBytes(); 510 * 511 * OutputStream out = null; 512 * try { 513 * out = new FileOutputStream("foo.txt"); 514 * out.write(data); 515 * out.close(); //close errors are handled 516 * } catch (IOException e) { 517 * // error handling 518 * } finally { 519 * IOUtils.closeQuietly(out); 520 * } 521 * </pre> 522 * 523 * @param output the OutputStream to close, may be null or already closed 524 * 525 * @deprecated As of 2.6 deprecated without replacement. Please use the try-with-resources statement or handle 526 * suppressed exceptions manually. 527 * @see Throwable#addSuppressed(java.lang.Throwable) 528 */ 529 @Deprecated 530 public static void closeQuietly(final OutputStream output) { 531 closeQuietly((Closeable) output); 532 } 533 534 /** 535 * Closes an <code>Reader</code> unconditionally. 536 * <p> 537 * Equivalent to {@link Reader#close()}, except any exceptions will be ignored. 538 * This is typically used in finally blocks. 539 * <p> 540 * Example code: 541 * <pre> 542 * char[] data = new char[1024]; 543 * Reader in = null; 544 * try { 545 * in = new FileReader("foo.txt"); 546 * in.read(data); 547 * in.close(); //close errors are handled 548 * } catch (Exception e) { 549 * // error handling 550 * } finally { 551 * IOUtils.closeQuietly(in); 552 * } 553 * </pre> 554 * 555 * @param input the Reader to close, may be null or already closed 556 * 557 * @deprecated As of 2.6 deprecated without replacement. Please use the try-with-resources statement or handle 558 * suppressed exceptions manually. 559 * @see Throwable#addSuppressed(java.lang.Throwable) 560 */ 561 @Deprecated 562 public static void closeQuietly(final Reader input) { 563 closeQuietly((Closeable) input); 564 } 565 566 /** 567 * Closes a <code>Selector</code> unconditionally. 568 * <p> 569 * Equivalent to {@link Selector#close()}, except any exceptions will be ignored. 570 * This is typically used in finally blocks. 571 * <p> 572 * Example code: 573 * <pre> 574 * Selector selector = null; 575 * try { 576 * selector = Selector.open(); 577 * // process socket 578 * 579 * } catch (Exception e) { 580 * // error handling 581 * } finally { 582 * IOUtils.closeQuietly(selector); 583 * } 584 * </pre> 585 * 586 * @param selector the Selector to close, may be null or already closed 587 * @since 2.2 588 * 589 * @deprecated As of 2.6 deprecated without replacement. Please use the try-with-resources statement or handle 590 * suppressed exceptions manually. 591 * @see Throwable#addSuppressed(java.lang.Throwable) 592 */ 593 @Deprecated 594 public static void closeQuietly(final Selector selector) { 595 closeQuietly((Closeable) selector); 596 } 597 598 /** 599 * Closes a <code>ServerSocket</code> unconditionally. 600 * <p> 601 * Equivalent to {@link ServerSocket#close()}, except any exceptions will be ignored. 602 * This is typically used in finally blocks. 603 * <p> 604 * Example code: 605 * <pre> 606 * ServerSocket socket = null; 607 * try { 608 * socket = new ServerSocket(); 609 * // process socket 610 * socket.close(); 611 * } catch (Exception e) { 612 * // error handling 613 * } finally { 614 * IOUtils.closeQuietly(socket); 615 * } 616 * </pre> 617 * 618 * @param serverSocket the ServerSocket to close, may be null or already closed 619 * @since 2.2 620 * 621 * @deprecated As of 2.6 deprecated without replacement. Please use the try-with-resources statement or handle 622 * suppressed exceptions manually. 623 * @see Throwable#addSuppressed(java.lang.Throwable) 624 */ 625 @Deprecated 626 public static void closeQuietly(final ServerSocket serverSocket) { 627 closeQuietly((Closeable) serverSocket); 628 } 629 630 /** 631 * Closes a <code>Socket</code> unconditionally. 632 * <p> 633 * Equivalent to {@link Socket#close()}, except any exceptions will be ignored. 634 * This is typically used in finally blocks. 635 * <p> 636 * Example code: 637 * <pre> 638 * Socket socket = null; 639 * try { 640 * socket = new Socket("http://www.foo.com/", 80); 641 * // process socket 642 * socket.close(); 643 * } catch (Exception e) { 644 * // error handling 645 * } finally { 646 * IOUtils.closeQuietly(socket); 647 * } 648 * </pre> 649 * 650 * @param socket the Socket to close, may be null or already closed 651 * @since 2.0 652 * 653 * @deprecated As of 2.6 deprecated without replacement. Please use the try-with-resources statement or handle 654 * suppressed exceptions manually. 655 * @see Throwable#addSuppressed(java.lang.Throwable) 656 */ 657 @Deprecated 658 public static void closeQuietly(final Socket socket) { 659 closeQuietly((Closeable) socket); 660 } 661 662 /** 663 * Closes an <code>Writer</code> unconditionally. 664 * <p> 665 * Equivalent to {@link Writer#close()}, except any exceptions will be ignored. 666 * This is typically used in finally blocks. 667 * <p> 668 * Example code: 669 * <pre> 670 * Writer out = null; 671 * try { 672 * out = new StringWriter(); 673 * out.write("Hello World"); 674 * out.close(); //close errors are handled 675 * } catch (Exception e) { 676 * // error handling 677 * } finally { 678 * IOUtils.closeQuietly(out); 679 * } 680 * </pre> 681 * 682 * @param output the Writer to close, may be null or already closed 683 * 684 * @deprecated As of 2.6 deprecated without replacement. Please use the try-with-resources statement or handle 685 * suppressed exceptions manually. 686 * @see Throwable#addSuppressed(java.lang.Throwable) 687 */ 688 @Deprecated 689 public static void closeQuietly(final Writer output) { 690 closeQuietly((Closeable) output); 691 } 692 693 /** 694 * Compares the contents of two Streams to determine if they are equal or 695 * not. 696 * <p> 697 * This method buffers the input internally using 698 * <code>BufferedInputStream</code> if they are not already buffered. 699 * </p> 700 * 701 * @param input1 the first stream 702 * @param input2 the second stream 703 * @return true if the content of the streams are equal or they both don't 704 * exist, false otherwise 705 * @throws NullPointerException if either input is null 706 * @throws IOException if an I/O error occurs 707 */ 708 @SuppressWarnings("resource") 709 public static boolean contentEquals(final InputStream input1, final InputStream input2) 710 throws IOException { 711 if (input1 == input2) { 712 return true; 713 } 714 if (input1 == null ^ input2 == null) { 715 return false; 716 } 717 final BufferedInputStream bufferedInput1 = buffer(input1); 718 final BufferedInputStream bufferedInput2 = buffer(input2); 719 int ch = bufferedInput1.read(); 720 while (EOF != ch) { 721 final int ch2 = bufferedInput2.read(); 722 if (ch != ch2) { 723 return false; 724 } 725 ch = bufferedInput1.read(); 726 } 727 return bufferedInput2.read() == EOF; 728 } 729 730 /** 731 * Compares the contents of two Readers to determine if they are equal or 732 * not. 733 * <p> 734 * This method buffers the input internally using 735 * <code>BufferedReader</code> if they are not already buffered. 736 * </p> 737 * 738 * @param input1 the first reader 739 * @param input2 the second reader 740 * @return true if the content of the readers are equal or they both don't 741 * exist, false otherwise 742 * @throws NullPointerException if either input is null 743 * @throws IOException if an I/O error occurs 744 * @since 1.1 745 */ 746 @SuppressWarnings("resource") 747 public static boolean contentEquals(final Reader input1, final Reader input2) 748 throws IOException { 749 if (input1 == input2) { 750 return true; 751 } 752 if (input1 == null ^ input2 == null) { 753 return false; 754 } 755 final BufferedReader bufferedInput1 = toBufferedReader(input1); 756 final BufferedReader bufferedInput2 = toBufferedReader(input2); 757 758 int ch = bufferedInput1.read(); 759 while (EOF != ch) { 760 final int ch2 = bufferedInput2.read(); 761 if (ch != ch2) { 762 return false; 763 } 764 ch = bufferedInput1.read(); 765 } 766 767 return bufferedInput2.read() == EOF; 768 } 769 770 /** 771 * Compares the contents of two Readers to determine if they are equal or 772 * not, ignoring EOL characters. 773 * <p> 774 * This method buffers the input internally using 775 * <code>BufferedReader</code> if they are not already buffered. 776 * 777 * @param input1 the first reader 778 * @param input2 the second reader 779 * @return true if the content of the readers are equal (ignoring EOL differences), false otherwise 780 * @throws NullPointerException if either input is null 781 * @throws IOException if an I/O error occurs 782 * @since 2.2 783 */ 784 @SuppressWarnings("resource") 785 public static boolean contentEqualsIgnoreEOL(final Reader input1, final Reader input2) 786 throws IOException { 787 if (input1 == input2) { 788 return true; 789 } 790 if (input1 == null ^ input2 == null) { 791 return false; 792 } 793 final BufferedReader br1 = toBufferedReader(input1); 794 final BufferedReader br2 = toBufferedReader(input2); 795 796 String line1 = br1.readLine(); 797 String line2 = br2.readLine(); 798 while (line1 != null && line1.equals(line2)) { 799 line1 = br1.readLine(); 800 line2 = br2.readLine(); 801 } 802 return Objects.equals(line1, line2); 803 } 804 805 /** 806 * Copies bytes from an <code>InputStream</code> to an 807 * <code>OutputStream</code>. 808 * <p> 809 * This method buffers the input internally, so there is no need to use a 810 * <code>BufferedInputStream</code>. 811 * <p> 812 * Large streams (over 2GB) will return a bytes copied value of 813 * <code>-1</code> after the copy has completed since the correct 814 * number of bytes cannot be returned as an int. For large streams 815 * use the <code>copyLarge(InputStream, OutputStream)</code> method. 816 * 817 * @param input the <code>InputStream</code> to read from 818 * @param output the <code>OutputStream</code> to write to 819 * @return the number of bytes copied, or -1 if > Integer.MAX_VALUE 820 * @throws NullPointerException if the input or output is null 821 * @throws IOException if an I/O error occurs 822 * @since 1.1 823 */ 824 public static int copy(final InputStream input, final OutputStream output) throws IOException { 825 final long count = copyLarge(input, output); 826 if (count > Integer.MAX_VALUE) { 827 return -1; 828 } 829 return (int) count; 830 } 831 832 /** 833 * Copies bytes from an <code>InputStream</code> to an <code>OutputStream</code> using an internal buffer of the 834 * given size. 835 * <p> 836 * This method buffers the input internally, so there is no need to use a <code>BufferedInputStream</code>. 837 * <p> 838 * 839 * @param input the <code>InputStream</code> to read from 840 * @param output the <code>OutputStream</code> to write to 841 * @param bufferSize the bufferSize used to copy from the input to the output 842 * @return the number of bytes copied 843 * @throws NullPointerException if the input or output is null 844 * @throws IOException if an I/O error occurs 845 * @since 2.5 846 */ 847 public static long copy(final InputStream input, final OutputStream output, final int bufferSize) 848 throws IOException { 849 return copyLarge(input, output, new byte[bufferSize]); 850 } 851 852 /** 853 * Copies bytes from an <code>InputStream</code> to chars on a 854 * <code>Writer</code> using the default character encoding of the platform. 855 * <p> 856 * This method buffers the input internally, so there is no need to use a 857 * <code>BufferedInputStream</code>. 858 * <p> 859 * This method uses {@link InputStreamReader}. 860 * 861 * @param input the <code>InputStream</code> to read from 862 * @param output the <code>Writer</code> to write to 863 * @throws NullPointerException if the input or output is null 864 * @throws IOException if an I/O error occurs 865 * @since 1.1 866 * @deprecated 2.5 use {@link #copy(InputStream, Writer, Charset)} instead 867 */ 868 @Deprecated 869 public static void copy(final InputStream input, final Writer output) 870 throws IOException { 871 copy(input, output, Charset.defaultCharset()); 872 } 873 874 /** 875 * Copies bytes from an <code>InputStream</code> to chars on a 876 * <code>Writer</code> using the specified character encoding. 877 * <p> 878 * This method buffers the input internally, so there is no need to use a 879 * <code>BufferedInputStream</code>. 880 * <p> 881 * This method uses {@link InputStreamReader}. 882 * 883 * @param input the <code>InputStream</code> to read from 884 * @param output the <code>Writer</code> to write to 885 * @param inputCharset the charser to use for the input stream, null means platform default 886 * @throws NullPointerException if the input or output is null 887 * @throws IOException if an I/O error occurs 888 * @since 2.3 889 */ 890 public static void copy(final InputStream input, final Writer output, final Charset inputCharset) 891 throws IOException { 892 final InputStreamReader in = new InputStreamReader(input, Charsets.toCharset(inputCharset)); 893 copy(in, output); 894 } 895 896 /** 897 * Copies bytes from an <code>InputStream</code> to chars on a 898 * <code>Writer</code> using the specified character encoding. 899 * <p> 900 * This method buffers the input internally, so there is no need to use a 901 * <code>BufferedInputStream</code>. 902 * <p> 903 * Character encoding names can be found at 904 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 905 * <p> 906 * This method uses {@link InputStreamReader}. 907 * 908 * @param input the <code>InputStream</code> to read from 909 * @param output the <code>Writer</code> to write to 910 * @param inputCharsetName the name of the requested charset for the InputStream, null means platform default 911 * @throws NullPointerException if the input or output is null 912 * @throws IOException if an I/O error occurs 913 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 914 * .UnsupportedEncodingException} in version 2.2 if the 915 * encoding is not supported. 916 * @since 1.1 917 */ 918 public static void copy(final InputStream input, final Writer output, final String inputCharsetName) 919 throws IOException { 920 copy(input, output, Charsets.toCharset(inputCharsetName)); 921 } 922 923 /** 924 * Copies chars from a <code>Reader</code> to a <code>Appendable</code>. 925 * <p> 926 * This method buffers the input internally, so there is no need to use a 927 * <code>BufferedReader</code>. 928 * <p> 929 * Large streams (over 2GB) will return a chars copied value of 930 * <code>-1</code> after the copy has completed since the correct 931 * number of chars cannot be returned as an int. For large streams 932 * use the <code>copyLarge(Reader, Writer)</code> method. 933 * 934 * @param input the <code>Reader</code> to read from 935 * @param output the <code>Appendable</code> to write to 936 * @return the number of characters copied, or -1 if > Integer.MAX_VALUE 937 * @throws NullPointerException if the input or output is null 938 * @throws IOException if an I/O error occurs 939 * @since 2.7 940 */ 941 public static long copy(final Reader input, final Appendable output) throws IOException { 942 return copy(input, output, CharBuffer.allocate(DEFAULT_BUFFER_SIZE)); 943 } 944 945 /** 946 * Copies chars from a <code>Reader</code> to an <code>Appendable</code>. 947 * <p> 948 * This method uses the provided buffer, so there is no need to use a 949 * <code>BufferedReader</code>. 950 * </p> 951 * 952 * @param input the <code>Reader</code> to read from 953 * @param output the <code>Appendable</code> to write to 954 * @param buffer the buffer to be used for the copy 955 * @return the number of characters copied 956 * @throws NullPointerException if the input or output is null 957 * @throws IOException if an I/O error occurs 958 * @since 2.7 959 */ 960 public static long copy(final Reader input, final Appendable output, final CharBuffer buffer) throws IOException { 961 long count = 0; 962 int n; 963 while (EOF != (n = input.read(buffer))) { 964 buffer.flip(); 965 output.append(buffer, 0, n); 966 count += n; 967 } 968 return count; 969 } 970 971 /** 972 * Copies chars from a <code>Reader</code> to bytes on an 973 * <code>OutputStream</code> using the default character encoding of the 974 * platform, and calling flush. 975 * <p> 976 * This method buffers the input internally, so there is no need to use a 977 * <code>BufferedReader</code>. 978 * <p> 979 * Due to the implementation of OutputStreamWriter, this method performs a 980 * flush. 981 * <p> 982 * This method uses {@link OutputStreamWriter}. 983 * 984 * @param input the <code>Reader</code> to read from 985 * @param output the <code>OutputStream</code> to write to 986 * @throws NullPointerException if the input or output is null 987 * @throws IOException if an I/O error occurs 988 * @since 1.1 989 * @deprecated 2.5 use {@link #copy(Reader, OutputStream, Charset)} instead 990 */ 991 @Deprecated 992 public static void copy(final Reader input, final OutputStream output) 993 throws IOException { 994 copy(input, output, Charset.defaultCharset()); 995 } 996 997 /** 998 * Copies chars from a <code>Reader</code> to bytes on an 999 * <code>OutputStream</code> using the specified character encoding, and 1000 * calling flush. 1001 * <p> 1002 * This method buffers the input internally, so there is no need to use a 1003 * <code>BufferedReader</code>. 1004 * </p> 1005 * <p> 1006 * Due to the implementation of OutputStreamWriter, this method performs a 1007 * flush. 1008 * </p> 1009 * <p> 1010 * This method uses {@link OutputStreamWriter}. 1011 * </p> 1012 * 1013 * @param input the <code>Reader</code> to read from 1014 * @param output the <code>OutputStream</code> to write to 1015 * @param outputCharset the charset to use for the OutputStream, null means platform default 1016 * @throws NullPointerException if the input or output is null 1017 * @throws IOException if an I/O error occurs 1018 * @since 2.3 1019 */ 1020 public static void copy(final Reader input, final OutputStream output, final Charset outputCharset) 1021 throws IOException { 1022 final OutputStreamWriter out = new OutputStreamWriter(output, Charsets.toCharset(outputCharset)); 1023 copy(input, out); 1024 // XXX Unless anyone is planning on rewriting OutputStreamWriter, 1025 // we have to flush here. 1026 out.flush(); 1027 } 1028 1029 /** 1030 * Copies chars from a <code>Reader</code> to bytes on an 1031 * <code>OutputStream</code> using the specified character encoding, and 1032 * calling flush. 1033 * <p> 1034 * This method buffers the input internally, so there is no need to use a 1035 * <code>BufferedReader</code>. 1036 * <p> 1037 * Character encoding names can be found at 1038 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 1039 * <p> 1040 * Due to the implementation of OutputStreamWriter, this method performs a 1041 * flush. 1042 * <p> 1043 * This method uses {@link OutputStreamWriter}. 1044 * 1045 * @param input the <code>Reader</code> to read from 1046 * @param output the <code>OutputStream</code> to write to 1047 * @param outputCharsetName the name of the requested charset for the OutputStream, null means platform default 1048 * @throws NullPointerException if the input or output is null 1049 * @throws IOException if an I/O error occurs 1050 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 1051 * .UnsupportedEncodingException} in version 2.2 if the 1052 * encoding is not supported. 1053 * @since 1.1 1054 */ 1055 public static void copy(final Reader input, final OutputStream output, final String outputCharsetName) 1056 throws IOException { 1057 copy(input, output, Charsets.toCharset(outputCharsetName)); 1058 } 1059 1060 /** 1061 * Copies chars from a <code>Reader</code> to a <code>Writer</code>. 1062 * <p> 1063 * This method buffers the input internally, so there is no need to use a 1064 * <code>BufferedReader</code>. 1065 * <p> 1066 * Large streams (over 2GB) will return a chars copied value of 1067 * <code>-1</code> after the copy has completed since the correct 1068 * number of chars cannot be returned as an int. For large streams 1069 * use the <code>copyLarge(Reader, Writer)</code> method. 1070 * 1071 * @param input the <code>Reader</code> to read from 1072 * @param output the <code>Writer</code> to write to 1073 * @return the number of characters copied, or -1 if > Integer.MAX_VALUE 1074 * @throws NullPointerException if the input or output is null 1075 * @throws IOException if an I/O error occurs 1076 * @since 1.1 1077 */ 1078 public static int copy(final Reader input, final Writer output) throws IOException { 1079 final long count = copyLarge(input, output); 1080 if (count > Integer.MAX_VALUE) { 1081 return -1; 1082 } 1083 return (int) count; 1084 } 1085 1086 /** 1087 * Copies bytes from a large (over 2GB) <code>InputStream</code> to an 1088 * <code>OutputStream</code>. 1089 * <p> 1090 * This method buffers the input internally, so there is no need to use a 1091 * <code>BufferedInputStream</code>. 1092 * <p> 1093 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. 1094 * 1095 * @param input the <code>InputStream</code> to read from 1096 * @param output the <code>OutputStream</code> to write to 1097 * @return the number of bytes copied 1098 * @throws NullPointerException if the input or output is null 1099 * @throws IOException if an I/O error occurs 1100 * @since 1.3 1101 */ 1102 public static long copyLarge(final InputStream input, final OutputStream output) 1103 throws IOException { 1104 return copy(input, output, DEFAULT_BUFFER_SIZE); 1105 } 1106 1107 /** 1108 * Copies bytes from a large (over 2GB) <code>InputStream</code> to an 1109 * <code>OutputStream</code>. 1110 * <p> 1111 * This method uses the provided buffer, so there is no need to use a 1112 * <code>BufferedInputStream</code>. 1113 * <p> 1114 * 1115 * @param input the <code>InputStream</code> to read from 1116 * @param output the <code>OutputStream</code> to write to 1117 * @param buffer the buffer to use for the copy 1118 * @return the number of bytes copied 1119 * @throws NullPointerException if the input or output is null 1120 * @throws IOException if an I/O error occurs 1121 * @since 2.2 1122 */ 1123 public static long copyLarge(final InputStream input, final OutputStream output, final byte[] buffer) 1124 throws IOException { 1125 long count = 0; 1126 int n; 1127 while (EOF != (n = input.read(buffer))) { 1128 output.write(buffer, 0, n); 1129 count += n; 1130 } 1131 return count; 1132 } 1133 1134 /** 1135 * Copies some or all bytes from a large (over 2GB) <code>InputStream</code> to an 1136 * <code>OutputStream</code>, optionally skipping input bytes. 1137 * <p> 1138 * This method buffers the input internally, so there is no need to use a 1139 * <code>BufferedInputStream</code>. 1140 * </p> 1141 * <p> 1142 * Note that the implementation uses {@link #skip(InputStream, long)}. 1143 * This means that the method may be considerably less efficient than using the actual skip implementation, 1144 * this is done to guarantee that the correct number of characters are skipped. 1145 * </p> 1146 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. 1147 * 1148 * @param input the <code>InputStream</code> to read from 1149 * @param output the <code>OutputStream</code> to write to 1150 * @param inputOffset : number of bytes to skip from input before copying 1151 * -ve values are ignored 1152 * @param length : number of bytes to copy. -ve means all 1153 * @return the number of bytes copied 1154 * @throws NullPointerException if the input or output is null 1155 * @throws IOException if an I/O error occurs 1156 * @since 2.2 1157 */ 1158 public static long copyLarge(final InputStream input, final OutputStream output, final long inputOffset, 1159 final long length) throws IOException { 1160 return copyLarge(input, output, inputOffset, length, new byte[DEFAULT_BUFFER_SIZE]); 1161 } 1162 1163 /** 1164 * Copies some or all bytes from a large (over 2GB) <code>InputStream</code> to an 1165 * <code>OutputStream</code>, optionally skipping input bytes. 1166 * <p> 1167 * This method uses the provided buffer, so there is no need to use a 1168 * <code>BufferedInputStream</code>. 1169 * </p> 1170 * <p> 1171 * Note that the implementation uses {@link #skip(InputStream, long)}. 1172 * This means that the method may be considerably less efficient than using the actual skip implementation, 1173 * this is done to guarantee that the correct number of characters are skipped. 1174 * </p> 1175 * 1176 * @param input the <code>InputStream</code> to read from 1177 * @param output the <code>OutputStream</code> to write to 1178 * @param inputOffset : number of bytes to skip from input before copying 1179 * -ve values are ignored 1180 * @param length : number of bytes to copy. -ve means all 1181 * @param buffer the buffer to use for the copy 1182 * @return the number of bytes copied 1183 * @throws NullPointerException if the input or output is null 1184 * @throws IOException if an I/O error occurs 1185 * @since 2.2 1186 */ 1187 public static long copyLarge(final InputStream input, final OutputStream output, 1188 final long inputOffset, final long length, final byte[] buffer) throws IOException { 1189 if (inputOffset > 0) { 1190 skipFully(input, inputOffset); 1191 } 1192 if (length == 0) { 1193 return 0; 1194 } 1195 final int bufferLength = buffer.length; 1196 int bytesToRead = bufferLength; 1197 if (length > 0 && length < bufferLength) { 1198 bytesToRead = (int) length; 1199 } 1200 int read; 1201 long totalRead = 0; 1202 while (bytesToRead > 0 && EOF != (read = input.read(buffer, 0, bytesToRead))) { 1203 output.write(buffer, 0, read); 1204 totalRead += read; 1205 if (length > 0) { // only adjust length if not reading to the end 1206 // Note the cast must work because buffer.length is an integer 1207 bytesToRead = (int) Math.min(length - totalRead, bufferLength); 1208 } 1209 } 1210 return totalRead; 1211 } 1212 1213 /** 1214 * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>. 1215 * <p> 1216 * This method buffers the input internally, so there is no need to use a 1217 * <code>BufferedReader</code>. 1218 * <p> 1219 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. 1220 * 1221 * @param input the <code>Reader</code> to read from 1222 * @param output the <code>Writer</code> to write to 1223 * @return the number of characters copied 1224 * @throws NullPointerException if the input or output is null 1225 * @throws IOException if an I/O error occurs 1226 * @since 1.3 1227 */ 1228 public static long copyLarge(final Reader input, final Writer output) throws IOException { 1229 return copyLarge(input, output, new char[DEFAULT_BUFFER_SIZE]); 1230 } 1231 1232 /** 1233 * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>. 1234 * <p> 1235 * This method uses the provided buffer, so there is no need to use a 1236 * <code>BufferedReader</code>. 1237 * <p> 1238 * 1239 * @param input the <code>Reader</code> to read from 1240 * @param output the <code>Writer</code> to write to 1241 * @param buffer the buffer to be used for the copy 1242 * @return the number of characters copied 1243 * @throws NullPointerException if the input or output is null 1244 * @throws IOException if an I/O error occurs 1245 * @since 2.2 1246 */ 1247 public static long copyLarge(final Reader input, final Writer output, final char[] buffer) throws IOException { 1248 long count = 0; 1249 int n; 1250 while (EOF != (n = input.read(buffer))) { 1251 output.write(buffer, 0, n); 1252 count += n; 1253 } 1254 return count; 1255 } 1256 1257 /** 1258 * Copies some or all chars from a large (over 2GB) <code>InputStream</code> to an 1259 * <code>OutputStream</code>, optionally skipping input chars. 1260 * <p> 1261 * This method buffers the input internally, so there is no need to use a 1262 * <code>BufferedReader</code>. 1263 * <p> 1264 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. 1265 * 1266 * @param input the <code>Reader</code> to read from 1267 * @param output the <code>Writer</code> to write to 1268 * @param inputOffset : number of chars to skip from input before copying 1269 * -ve values are ignored 1270 * @param length : number of chars to copy. -ve means all 1271 * @return the number of chars copied 1272 * @throws NullPointerException if the input or output is null 1273 * @throws IOException if an I/O error occurs 1274 * @since 2.2 1275 */ 1276 public static long copyLarge(final Reader input, final Writer output, final long inputOffset, final long length) 1277 throws IOException { 1278 return copyLarge(input, output, inputOffset, length, new char[DEFAULT_BUFFER_SIZE]); 1279 } 1280 1281 /** 1282 * Copies some or all chars from a large (over 2GB) <code>InputStream</code> to an 1283 * <code>OutputStream</code>, optionally skipping input chars. 1284 * <p> 1285 * This method uses the provided buffer, so there is no need to use a 1286 * <code>BufferedReader</code>. 1287 * <p> 1288 * 1289 * @param input the <code>Reader</code> to read from 1290 * @param output the <code>Writer</code> to write to 1291 * @param inputOffset : number of chars to skip from input before copying 1292 * -ve values are ignored 1293 * @param length : number of chars to copy. -ve means all 1294 * @param buffer the buffer to be used for the copy 1295 * @return the number of chars copied 1296 * @throws NullPointerException if the input or output is null 1297 * @throws IOException if an I/O error occurs 1298 * @since 2.2 1299 */ 1300 public static long copyLarge(final Reader input, final Writer output, final long inputOffset, final long length, 1301 final char[] buffer) 1302 throws IOException { 1303 if (inputOffset > 0) { 1304 skipFully(input, inputOffset); 1305 } 1306 if (length == 0) { 1307 return 0; 1308 } 1309 int bytesToRead = buffer.length; 1310 if (length > 0 && length < buffer.length) { 1311 bytesToRead = (int) length; 1312 } 1313 int read; 1314 long totalRead = 0; 1315 while (bytesToRead > 0 && EOF != (read = input.read(buffer, 0, bytesToRead))) { 1316 output.write(buffer, 0, read); 1317 totalRead += read; 1318 if (length > 0) { // only adjust length if not reading to the end 1319 // Note the cast must work because buffer.length is an integer 1320 bytesToRead = (int) Math.min(length - totalRead, buffer.length); 1321 } 1322 } 1323 return totalRead; 1324 } 1325 1326 /** 1327 * Returns the length of the given array in a null-safe manner. 1328 * 1329 * @param array an array or null 1330 * @return the array length -- or 0 if the given array is null. 1331 * @since 2.7 1332 */ 1333 public static int length(final byte[] array) { 1334 return array == null ? 0 : array.length; 1335 } 1336 1337 /** 1338 * Returns the length of the given array in a null-safe manner. 1339 * 1340 * @param array an array or null 1341 * @return the array length -- or 0 if the given array is null. 1342 * @since 2.7 1343 */ 1344 public static int length(final char[] array) { 1345 return array == null ? 0 : array.length; 1346 } 1347 1348 /** 1349 * Returns the length of the given CharSequence in a null-safe manner. 1350 * 1351 * @param csq a CharSequence or null 1352 * @return the CharSequence length -- or 0 if the given CharSequence is null. 1353 * @since 2.7 1354 */ 1355 public static int length(final CharSequence csq) { 1356 return csq == null ? 0 : csq.length(); 1357 } 1358 1359 /** 1360 * Returns the length of the given array in a null-safe manner. 1361 * 1362 * @param array an array or null 1363 * @return the array length -- or 0 if the given array is null. 1364 * @since 2.7 1365 */ 1366 public static int length(final Object[] array) { 1367 return array == null ? 0 : array.length; 1368 } 1369 1370 /** 1371 * Returns an Iterator for the lines in an <code>InputStream</code>, using 1372 * the character encoding specified (or default encoding if null). 1373 * <p> 1374 * <code>LineIterator</code> holds a reference to the open 1375 * <code>InputStream</code> specified here. When you have finished with 1376 * the iterator you should close the stream to free internal resources. 1377 * This can be done by closing the stream directly, or by calling 1378 * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}. 1379 * <p> 1380 * The recommended usage pattern is: 1381 * <pre> 1382 * try { 1383 * LineIterator it = IOUtils.lineIterator(stream, charset); 1384 * while (it.hasNext()) { 1385 * String line = it.nextLine(); 1386 * /// do something with line 1387 * } 1388 * } finally { 1389 * IOUtils.closeQuietly(stream); 1390 * } 1391 * </pre> 1392 * 1393 * @param input the <code>InputStream</code> to read from, not null 1394 * @param charset the charset to use, null means platform default 1395 * @return an Iterator of the lines in the reader, never null 1396 * @throws IllegalArgumentException if the input is null 1397 * @throws IOException if an I/O error occurs, such as if the encoding is invalid 1398 * @since 2.3 1399 */ 1400 public static LineIterator lineIterator(final InputStream input, final Charset charset) throws IOException { 1401 return new LineIterator(new InputStreamReader(input, Charsets.toCharset(charset))); 1402 } 1403 1404 /** 1405 * Returns an Iterator for the lines in an <code>InputStream</code>, using 1406 * the character encoding specified (or default encoding if null). 1407 * <p> 1408 * <code>LineIterator</code> holds a reference to the open 1409 * <code>InputStream</code> specified here. When you have finished with 1410 * the iterator you should close the stream to free internal resources. 1411 * This can be done by closing the stream directly, or by calling 1412 * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}. 1413 * <p> 1414 * The recommended usage pattern is: 1415 * <pre> 1416 * try { 1417 * LineIterator it = IOUtils.lineIterator(stream, "UTF-8"); 1418 * while (it.hasNext()) { 1419 * String line = it.nextLine(); 1420 * /// do something with line 1421 * } 1422 * } finally { 1423 * IOUtils.closeQuietly(stream); 1424 * } 1425 * </pre> 1426 * 1427 * @param input the <code>InputStream</code> to read from, not null 1428 * @param charsetName the encoding to use, null means platform default 1429 * @return an Iterator of the lines in the reader, never null 1430 * @throws IllegalArgumentException if the input is null 1431 * @throws IOException if an I/O error occurs, such as if the encoding is invalid 1432 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 1433 * .UnsupportedEncodingException} in version 2.2 if the 1434 * encoding is not supported. 1435 * @since 1.2 1436 */ 1437 public static LineIterator lineIterator(final InputStream input, final String charsetName) throws IOException { 1438 return lineIterator(input, Charsets.toCharset(charsetName)); 1439 } 1440 1441 /** 1442 * Returns an Iterator for the lines in a <code>Reader</code>. 1443 * <p> 1444 * <code>LineIterator</code> holds a reference to the open 1445 * <code>Reader</code> specified here. When you have finished with the 1446 * iterator you should close the reader to free internal resources. 1447 * This can be done by closing the reader directly, or by calling 1448 * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}. 1449 * <p> 1450 * The recommended usage pattern is: 1451 * <pre> 1452 * try { 1453 * LineIterator it = IOUtils.lineIterator(reader); 1454 * while (it.hasNext()) { 1455 * String line = it.nextLine(); 1456 * /// do something with line 1457 * } 1458 * } finally { 1459 * IOUtils.closeQuietly(reader); 1460 * } 1461 * </pre> 1462 * 1463 * @param reader the <code>Reader</code> to read from, not null 1464 * @return an Iterator of the lines in the reader, never null 1465 * @throws IllegalArgumentException if the reader is null 1466 * @since 1.2 1467 */ 1468 public static LineIterator lineIterator(final Reader reader) { 1469 return new LineIterator(reader); 1470 } 1471 1472 /** 1473 * Reads bytes from an input stream. 1474 * This implementation guarantees that it will read as many bytes 1475 * as possible before giving up; this may not always be the case for 1476 * subclasses of {@link InputStream}. 1477 * 1478 * @param input where to read input from 1479 * @param buffer destination 1480 * @return actual length read; may be less than requested if EOF was reached 1481 * @throws IOException if a read error occurs 1482 * @since 2.2 1483 */ 1484 public static int read(final InputStream input, final byte[] buffer) throws IOException { 1485 return read(input, buffer, 0, buffer.length); 1486 } 1487 1488 /** 1489 * Reads bytes from an input stream. 1490 * This implementation guarantees that it will read as many bytes 1491 * as possible before giving up; this may not always be the case for 1492 * subclasses of {@link InputStream}. 1493 * 1494 * @param input where to read input from 1495 * @param buffer destination 1496 * @param offset initial offset into buffer 1497 * @param length length to read, must be >= 0 1498 * @return actual length read; may be less than requested if EOF was reached 1499 * @throws IOException if a read error occurs 1500 * @since 2.2 1501 */ 1502 public static int read(final InputStream input, final byte[] buffer, final int offset, final int length) 1503 throws IOException { 1504 if (length < 0) { 1505 throw new IllegalArgumentException("Length must not be negative: " + length); 1506 } 1507 int remaining = length; 1508 while (remaining > 0) { 1509 final int location = length - remaining; 1510 final int count = input.read(buffer, offset + location, remaining); 1511 if (EOF == count) { // EOF 1512 break; 1513 } 1514 remaining -= count; 1515 } 1516 return length - remaining; 1517 } 1518 1519 /** 1520 * Reads bytes from a ReadableByteChannel. 1521 * <p> 1522 * This implementation guarantees that it will read as many bytes 1523 * as possible before giving up; this may not always be the case for 1524 * subclasses of {@link ReadableByteChannel}. 1525 * 1526 * @param input the byte channel to read 1527 * @param buffer byte buffer destination 1528 * @return the actual length read; may be less than requested if EOF was reached 1529 * @throws IOException if a read error occurs 1530 * @since 2.5 1531 */ 1532 public static int read(final ReadableByteChannel input, final ByteBuffer buffer) throws IOException { 1533 final int length = buffer.remaining(); 1534 while (buffer.remaining() > 0) { 1535 final int count = input.read(buffer); 1536 if (EOF == count) { // EOF 1537 break; 1538 } 1539 } 1540 return length - buffer.remaining(); 1541 } 1542 1543 /** 1544 * Reads characters from an input character stream. 1545 * This implementation guarantees that it will read as many characters 1546 * as possible before giving up; this may not always be the case for 1547 * subclasses of {@link Reader}. 1548 * 1549 * @param input where to read input from 1550 * @param buffer destination 1551 * @return actual length read; may be less than requested if EOF was reached 1552 * @throws IOException if a read error occurs 1553 * @since 2.2 1554 */ 1555 public static int read(final Reader input, final char[] buffer) throws IOException { 1556 return read(input, buffer, 0, buffer.length); 1557 } 1558 1559 /** 1560 * Reads characters from an input character stream. 1561 * This implementation guarantees that it will read as many characters 1562 * as possible before giving up; this may not always be the case for 1563 * subclasses of {@link Reader}. 1564 * 1565 * @param input where to read input from 1566 * @param buffer destination 1567 * @param offset initial offset into buffer 1568 * @param length length to read, must be >= 0 1569 * @return actual length read; may be less than requested if EOF was reached 1570 * @throws IOException if a read error occurs 1571 * @since 2.2 1572 */ 1573 public static int read(final Reader input, final char[] buffer, final int offset, final int length) 1574 throws IOException { 1575 if (length < 0) { 1576 throw new IllegalArgumentException("Length must not be negative: " + length); 1577 } 1578 int remaining = length; 1579 while (remaining > 0) { 1580 final int location = length - remaining; 1581 final int count = input.read(buffer, offset + location, remaining); 1582 if (EOF == count) { // EOF 1583 break; 1584 } 1585 remaining -= count; 1586 } 1587 return length - remaining; 1588 } 1589 1590 /** 1591 * Reads the requested number of bytes or fail if there are not enough left. 1592 * <p> 1593 * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may 1594 * not read as many bytes as requested (most likely because of reaching EOF). 1595 * 1596 * @param input where to read input from 1597 * @param buffer destination 1598 * 1599 * @throws IOException if there is a problem reading the file 1600 * @throws IllegalArgumentException if length is negative 1601 * @throws EOFException if the number of bytes read was incorrect 1602 * @since 2.2 1603 */ 1604 public static void readFully(final InputStream input, final byte[] buffer) throws IOException { 1605 readFully(input, buffer, 0, buffer.length); 1606 } 1607 1608 /** 1609 * Reads the requested number of bytes or fail if there are not enough left. 1610 * <p> 1611 * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may 1612 * not read as many bytes as requested (most likely because of reaching EOF). 1613 * 1614 * @param input where to read input from 1615 * @param buffer destination 1616 * @param offset initial offset into buffer 1617 * @param length length to read, must be >= 0 1618 * 1619 * @throws IOException if there is a problem reading the file 1620 * @throws IllegalArgumentException if length is negative 1621 * @throws EOFException if the number of bytes read was incorrect 1622 * @since 2.2 1623 */ 1624 public static void readFully(final InputStream input, final byte[] buffer, final int offset, final int length) 1625 throws IOException { 1626 final int actual = read(input, buffer, offset, length); 1627 if (actual != length) { 1628 throw new EOFException("Length to read: " + length + " actual: " + actual); 1629 } 1630 } 1631 1632 /** 1633 * Reads the requested number of bytes or fail if there are not enough left. 1634 * <p> 1635 * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may 1636 * not read as many bytes as requested (most likely because of reaching EOF). 1637 * 1638 * @param input where to read input from 1639 * @param length length to read, must be >= 0 1640 * @return the bytes read from input 1641 * @throws IOException if there is a problem reading the file 1642 * @throws IllegalArgumentException if length is negative 1643 * @throws EOFException if the number of bytes read was incorrect 1644 * @since 2.5 1645 */ 1646 public static byte[] readFully(final InputStream input, final int length) throws IOException { 1647 final byte[] buffer = new byte[length]; 1648 readFully(input, buffer, 0, buffer.length); 1649 return buffer; 1650 } 1651 1652 /** 1653 * Reads the requested number of bytes or fail if there are not enough left. 1654 * <p> 1655 * This allows for the possibility that {@link ReadableByteChannel#read(ByteBuffer)} may 1656 * not read as many bytes as requested (most likely because of reaching EOF). 1657 * 1658 * @param input the byte channel to read 1659 * @param buffer byte buffer destination 1660 * @throws IOException if there is a problem reading the file 1661 * @throws EOFException if the number of bytes read was incorrect 1662 * @since 2.5 1663 */ 1664 public static void readFully(final ReadableByteChannel input, final ByteBuffer buffer) throws IOException { 1665 final int expected = buffer.remaining(); 1666 final int actual = read(input, buffer); 1667 if (actual != expected) { 1668 throw new EOFException("Length to read: " + expected + " actual: " + actual); 1669 } 1670 } 1671 1672 /** 1673 * Reads the requested number of characters or fail if there are not enough left. 1674 * <p> 1675 * This allows for the possibility that {@link Reader#read(char[], int, int)} may 1676 * not read as many characters as requested (most likely because of reaching EOF). 1677 * 1678 * @param input where to read input from 1679 * @param buffer destination 1680 * @throws IOException if there is a problem reading the file 1681 * @throws IllegalArgumentException if length is negative 1682 * @throws EOFException if the number of characters read was incorrect 1683 * @since 2.2 1684 */ 1685 public static void readFully(final Reader input, final char[] buffer) throws IOException { 1686 readFully(input, buffer, 0, buffer.length); 1687 } 1688 1689 /** 1690 * Reads the requested number of characters or fail if there are not enough left. 1691 * <p> 1692 * This allows for the possibility that {@link Reader#read(char[], int, int)} may 1693 * not read as many characters as requested (most likely because of reaching EOF). 1694 * 1695 * @param input where to read input from 1696 * @param buffer destination 1697 * @param offset initial offset into buffer 1698 * @param length length to read, must be >= 0 1699 * @throws IOException if there is a problem reading the file 1700 * @throws IllegalArgumentException if length is negative 1701 * @throws EOFException if the number of characters read was incorrect 1702 * @since 2.2 1703 */ 1704 public static void readFully(final Reader input, final char[] buffer, final int offset, final int length) 1705 throws IOException { 1706 final int actual = read(input, buffer, offset, length); 1707 if (actual != length) { 1708 throw new EOFException("Length to read: " + length + " actual: " + actual); 1709 } 1710 } 1711 1712 /** 1713 * Gets the contents of an <code>InputStream</code> as a list of Strings, 1714 * one entry per line, using the default character encoding of the platform. 1715 * <p> 1716 * This method buffers the input internally, so there is no need to use a 1717 * <code>BufferedInputStream</code>. 1718 * 1719 * @param input the <code>InputStream</code> to read from, not null 1720 * @return the list of Strings, never null 1721 * @throws NullPointerException if the input is null 1722 * @throws IOException if an I/O error occurs 1723 * @since 1.1 1724 * @deprecated 2.5 use {@link #readLines(InputStream, Charset)} instead 1725 */ 1726 @Deprecated 1727 public static List<String> readLines(final InputStream input) throws IOException { 1728 return readLines(input, Charset.defaultCharset()); 1729 } 1730 1731 /** 1732 * Gets the contents of an <code>InputStream</code> as a list of Strings, 1733 * one entry per line, using the specified character encoding. 1734 * <p> 1735 * This method buffers the input internally, so there is no need to use a 1736 * <code>BufferedInputStream</code>. 1737 * 1738 * @param input the <code>InputStream</code> to read from, not null 1739 * @param charset the charset to use, null means platform default 1740 * @return the list of Strings, never null 1741 * @throws NullPointerException if the input is null 1742 * @throws IOException if an I/O error occurs 1743 * @since 2.3 1744 */ 1745 public static List<String> readLines(final InputStream input, final Charset charset) throws IOException { 1746 final InputStreamReader reader = new InputStreamReader(input, Charsets.toCharset(charset)); 1747 return readLines(reader); 1748 } 1749 1750 /** 1751 * Gets the contents of an <code>InputStream</code> as a list of Strings, 1752 * one entry per line, using the specified character encoding. 1753 * <p> 1754 * Character encoding names can be found at 1755 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 1756 * <p> 1757 * This method buffers the input internally, so there is no need to use a 1758 * <code>BufferedInputStream</code>. 1759 * 1760 * @param input the <code>InputStream</code> to read from, not null 1761 * @param charsetName the name of the requested charset, null means platform default 1762 * @return the list of Strings, never null 1763 * @throws NullPointerException if the input is null 1764 * @throws IOException if an I/O error occurs 1765 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 1766 * .UnsupportedEncodingException} in version 2.2 if the 1767 * encoding is not supported. 1768 * @since 1.1 1769 */ 1770 public static List<String> readLines(final InputStream input, final String charsetName) throws IOException { 1771 return readLines(input, Charsets.toCharset(charsetName)); 1772 } 1773 1774 /** 1775 * Gets the contents of a <code>Reader</code> as a list of Strings, 1776 * one entry per line. 1777 * <p> 1778 * This method buffers the input internally, so there is no need to use a 1779 * <code>BufferedReader</code>. 1780 * 1781 * @param input the <code>Reader</code> to read from, not null 1782 * @return the list of Strings, never null 1783 * @throws NullPointerException if the input is null 1784 * @throws IOException if an I/O error occurs 1785 * @since 1.1 1786 */ 1787 public static List<String> readLines(final Reader input) throws IOException { 1788 final BufferedReader reader = toBufferedReader(input); 1789 final List<String> list = new ArrayList<>(); 1790 String line = reader.readLine(); 1791 while (line != null) { 1792 list.add(line); 1793 line = reader.readLine(); 1794 } 1795 return list; 1796 } 1797 1798 /** 1799 * Gets the contents of a classpath resource as a byte array. 1800 * 1801 * <p> 1802 * It is expected the given <code>name</code> to be absolute. The 1803 * behavior is not well-defined otherwise. 1804 * </p> 1805 * 1806 * @param name name of the desired resource 1807 * @return the requested byte array 1808 * @throws IOException if an I/O error occurs 1809 * 1810 * @since 2.6 1811 */ 1812 public static byte[] resourceToByteArray(final String name) throws IOException { 1813 return resourceToByteArray(name, null); 1814 } 1815 1816 /** 1817 * Gets the contents of a classpath resource as a byte array. 1818 * 1819 * <p> 1820 * It is expected the given <code>name</code> to be absolute. The 1821 * behavior is not well-defined otherwise. 1822 * </p> 1823 * 1824 * @param name name of the desired resource 1825 * @param classLoader the class loader that the resolution of the resource is delegated to 1826 * @return the requested byte array 1827 * @throws IOException if an I/O error occurs 1828 * 1829 * @since 2.6 1830 */ 1831 public static byte[] resourceToByteArray(final String name, final ClassLoader classLoader) throws IOException { 1832 return toByteArray(resourceToURL(name, classLoader)); 1833 } 1834 1835 /** 1836 * Gets the contents of a classpath resource as a String using the 1837 * specified character encoding. 1838 * 1839 * <p> 1840 * It is expected the given <code>name</code> to be absolute. The 1841 * behavior is not well-defined otherwise. 1842 * </p> 1843 * 1844 * @param name name of the desired resource 1845 * @param charset the charset to use, null means platform default 1846 * @return the requested String 1847 * @throws IOException if an I/O error occurs 1848 * 1849 * @since 2.6 1850 */ 1851 public static String resourceToString(final String name, final Charset charset) throws IOException { 1852 return resourceToString(name, charset, null); 1853 } 1854 1855 /** 1856 * Gets the contents of a classpath resource as a String using the 1857 * specified character encoding. 1858 * 1859 * <p> 1860 * It is expected the given <code>name</code> to be absolute. The 1861 * behavior is not well-defined otherwise. 1862 * </p> 1863 * 1864 * @param name name of the desired resource 1865 * @param charset the charset to use, null means platform default 1866 * @param classLoader the class loader that the resolution of the resource is delegated to 1867 * @return the requested String 1868 * @throws IOException if an I/O error occurs 1869 * 1870 * @since 2.6 1871 */ 1872 public static String resourceToString(final String name, final Charset charset, final ClassLoader classLoader) throws IOException { 1873 return toString(resourceToURL(name, classLoader), charset); 1874 } 1875 1876 /** 1877 * Gets a URL pointing to the given classpath resource. 1878 * 1879 * <p> 1880 * It is expected the given <code>name</code> to be absolute. The 1881 * behavior is not well-defined otherwise. 1882 * </p> 1883 * 1884 * @param name name of the desired resource 1885 * @return the requested URL 1886 * @throws IOException if an I/O error occurs 1887 * 1888 * @since 2.6 1889 */ 1890 public static URL resourceToURL(final String name) throws IOException { 1891 return resourceToURL(name, null); 1892 } 1893 1894 /** 1895 * Gets a URL pointing to the given classpath resource. 1896 * 1897 * <p> 1898 * It is expected the given <code>name</code> to be absolute. The 1899 * behavior is not well-defined otherwise. 1900 * </p> 1901 * 1902 * @param name name of the desired resource 1903 * @param classLoader the class loader that the resolution of the resource is delegated to 1904 * @return the requested URL 1905 * @throws IOException if an I/O error occurs 1906 * 1907 * @since 2.6 1908 */ 1909 public static URL resourceToURL(final String name, final ClassLoader classLoader) throws IOException { 1910 // What about the thread context class loader? 1911 // What about the system class loader? 1912 final URL resource = classLoader == null ? IOUtils.class.getResource(name) : classLoader.getResource(name); 1913 1914 if (resource == null) { 1915 throw new IOException("Resource not found: " + name); 1916 } 1917 1918 return resource; 1919 } 1920 1921 /** 1922 * Skips bytes from an input byte stream. 1923 * This implementation guarantees that it will read as many bytes 1924 * as possible before giving up; this may not always be the case for 1925 * skip() implementations in subclasses of {@link InputStream}. 1926 * <p> 1927 * Note that the implementation uses {@link InputStream#read(byte[], int, int)} rather 1928 * than delegating to {@link InputStream#skip(long)}. 1929 * This means that the method may be considerably less efficient than using the actual skip implementation, 1930 * this is done to guarantee that the correct number of bytes are skipped. 1931 * </p> 1932 * 1933 * @param input byte stream to skip 1934 * @param toSkip number of bytes to skip. 1935 * @return number of bytes actually skipped. 1936 * @throws IOException if there is a problem reading the file 1937 * @throws IllegalArgumentException if toSkip is negative 1938 * @see InputStream#skip(long) 1939 * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a> 1940 * @since 2.0 1941 */ 1942 public static long skip(final InputStream input, final long toSkip) throws IOException { 1943 if (toSkip < 0) { 1944 throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip); 1945 } 1946 /* 1947 * N.B. no need to synchronize this because: - we don't care if the buffer is created multiple times (the data 1948 * is ignored) - we always use the same size buffer, so if it it is recreated it will still be OK (if the buffer 1949 * size were variable, we would need to synch. to ensure some other thread did not create a smaller one) 1950 */ 1951 if (SKIP_BYTE_BUFFER == null) { 1952 SKIP_BYTE_BUFFER = new byte[SKIP_BUFFER_SIZE]; 1953 } 1954 long remain = toSkip; 1955 while (remain > 0) { 1956 // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip() 1957 final long n = input.read(SKIP_BYTE_BUFFER, 0, (int) Math.min(remain, SKIP_BUFFER_SIZE)); 1958 if (n < 0) { // EOF 1959 break; 1960 } 1961 remain -= n; 1962 } 1963 return toSkip - remain; 1964 } 1965 1966 /** 1967 * Skips bytes from a ReadableByteChannel. 1968 * This implementation guarantees that it will read as many bytes 1969 * as possible before giving up. 1970 * 1971 * @param input ReadableByteChannel to skip 1972 * @param toSkip number of bytes to skip. 1973 * @return number of bytes actually skipped. 1974 * @throws IOException if there is a problem reading the ReadableByteChannel 1975 * @throws IllegalArgumentException if toSkip is negative 1976 * @since 2.5 1977 */ 1978 public static long skip(final ReadableByteChannel input, final long toSkip) throws IOException { 1979 if (toSkip < 0) { 1980 throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip); 1981 } 1982 final ByteBuffer skipByteBuffer = ByteBuffer.allocate((int) Math.min(toSkip, SKIP_BUFFER_SIZE)); 1983 long remain = toSkip; 1984 while (remain > 0) { 1985 skipByteBuffer.position(0); 1986 skipByteBuffer.limit((int) Math.min(remain, SKIP_BUFFER_SIZE)); 1987 final int n = input.read(skipByteBuffer); 1988 if (n == EOF) { 1989 break; 1990 } 1991 remain -= n; 1992 } 1993 return toSkip - remain; 1994 } 1995 1996 /** 1997 * Skips characters from an input character stream. 1998 * This implementation guarantees that it will read as many characters 1999 * as possible before giving up; this may not always be the case for 2000 * skip() implementations in subclasses of {@link Reader}. 2001 * <p> 2002 * Note that the implementation uses {@link Reader#read(char[], int, int)} rather 2003 * than delegating to {@link Reader#skip(long)}. 2004 * This means that the method may be considerably less efficient than using the actual skip implementation, 2005 * this is done to guarantee that the correct number of characters are skipped. 2006 * </p> 2007 * 2008 * @param input character stream to skip 2009 * @param toSkip number of characters to skip. 2010 * @return number of characters actually skipped. 2011 * @throws IOException if there is a problem reading the file 2012 * @throws IllegalArgumentException if toSkip is negative 2013 * @see Reader#skip(long) 2014 * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a> 2015 * @since 2.0 2016 */ 2017 public static long skip(final Reader input, final long toSkip) throws IOException { 2018 if (toSkip < 0) { 2019 throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip); 2020 } 2021 /* 2022 * N.B. no need to synchronize this because: - we don't care if the buffer is created multiple times (the data 2023 * is ignored) - we always use the same size buffer, so if it it is recreated it will still be OK (if the buffer 2024 * size were variable, we would need to synch. to ensure some other thread did not create a smaller one) 2025 */ 2026 if (SKIP_CHAR_BUFFER == null) { 2027 SKIP_CHAR_BUFFER = new char[SKIP_BUFFER_SIZE]; 2028 } 2029 long remain = toSkip; 2030 while (remain > 0) { 2031 // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip() 2032 final long n = input.read(SKIP_CHAR_BUFFER, 0, (int) Math.min(remain, SKIP_BUFFER_SIZE)); 2033 if (n < 0) { // EOF 2034 break; 2035 } 2036 remain -= n; 2037 } 2038 return toSkip - remain; 2039 } 2040 2041 /** 2042 * Skips the requested number of bytes or fail if there are not enough left. 2043 * <p> 2044 * This allows for the possibility that {@link InputStream#skip(long)} may 2045 * not skip as many bytes as requested (most likely because of reaching EOF). 2046 * <p> 2047 * Note that the implementation uses {@link #skip(InputStream, long)}. 2048 * This means that the method may be considerably less efficient than using the actual skip implementation, 2049 * this is done to guarantee that the correct number of characters are skipped. 2050 * </p> 2051 * 2052 * @param input stream to skip 2053 * @param toSkip the number of bytes to skip 2054 * @throws IOException if there is a problem reading the file 2055 * @throws IllegalArgumentException if toSkip is negative 2056 * @throws EOFException if the number of bytes skipped was incorrect 2057 * @see InputStream#skip(long) 2058 * @since 2.0 2059 */ 2060 public static void skipFully(final InputStream input, final long toSkip) throws IOException { 2061 if (toSkip < 0) { 2062 throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip); 2063 } 2064 final long skipped = skip(input, toSkip); 2065 if (skipped != toSkip) { 2066 throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped); 2067 } 2068 } 2069 2070 /** 2071 * Skips the requested number of bytes or fail if there are not enough left. 2072 * 2073 * @param input ReadableByteChannel to skip 2074 * @param toSkip the number of bytes to skip 2075 * @throws IOException if there is a problem reading the ReadableByteChannel 2076 * @throws IllegalArgumentException if toSkip is negative 2077 * @throws EOFException if the number of bytes skipped was incorrect 2078 * @since 2.5 2079 */ 2080 public static void skipFully(final ReadableByteChannel input, final long toSkip) throws IOException { 2081 if (toSkip < 0) { 2082 throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip); 2083 } 2084 final long skipped = skip(input, toSkip); 2085 if (skipped != toSkip) { 2086 throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped); 2087 } 2088 } 2089 2090 /** 2091 * Skips the requested number of characters or fail if there are not enough left. 2092 * <p> 2093 * This allows for the possibility that {@link Reader#skip(long)} may 2094 * not skip as many characters as requested (most likely because of reaching EOF). 2095 * <p> 2096 * Note that the implementation uses {@link #skip(Reader, long)}. 2097 * This means that the method may be considerably less efficient than using the actual skip implementation, 2098 * this is done to guarantee that the correct number of characters are skipped. 2099 * </p> 2100 * 2101 * @param input stream to skip 2102 * @param toSkip the number of characters to skip 2103 * @throws IOException if there is a problem reading the file 2104 * @throws IllegalArgumentException if toSkip is negative 2105 * @throws EOFException if the number of characters skipped was incorrect 2106 * @see Reader#skip(long) 2107 * @since 2.0 2108 */ 2109 public static void skipFully(final Reader input, final long toSkip) throws IOException { 2110 final long skipped = skip(input, toSkip); 2111 if (skipped != toSkip) { 2112 throw new EOFException("Chars to skip: " + toSkip + " actual: " + skipped); 2113 } 2114 } 2115 2116 /** 2117 * Fetches entire contents of an <code>InputStream</code> and represent 2118 * same data as result InputStream. 2119 * <p> 2120 * This method is useful where, 2121 * <ul> 2122 * <li>Source InputStream is slow.</li> 2123 * <li>It has network resources associated, so we cannot keep it open for 2124 * long time.</li> 2125 * <li>It has network timeout associated.</li> 2126 * </ul> 2127 * It can be used in favor of {@link #toByteArray(InputStream)}, since it 2128 * avoids unnecessary allocation and copy of byte[].<br> 2129 * This method buffers the input internally, so there is no need to use a 2130 * <code>BufferedInputStream</code>. 2131 * 2132 * @param input Stream to be fully buffered. 2133 * @return A fully buffered stream. 2134 * @throws IOException if an I/O error occurs 2135 * @since 2.0 2136 */ 2137 public static InputStream toBufferedInputStream(final InputStream input) throws IOException { 2138 return ByteArrayOutputStream.toBufferedInputStream(input); 2139 } 2140 2141 /** 2142 * Fetches entire contents of an <code>InputStream</code> and represent 2143 * same data as result InputStream. 2144 * <p> 2145 * This method is useful where, 2146 * <ul> 2147 * <li>Source InputStream is slow.</li> 2148 * <li>It has network resources associated, so we cannot keep it open for 2149 * long time.</li> 2150 * <li>It has network timeout associated.</li> 2151 * </ul> 2152 * It can be used in favor of {@link #toByteArray(InputStream)}, since it 2153 * avoids unnecessary allocation and copy of byte[].<br> 2154 * This method buffers the input internally, so there is no need to use a 2155 * <code>BufferedInputStream</code>. 2156 * 2157 * @param input Stream to be fully buffered. 2158 * @param size the initial buffer size 2159 * @return A fully buffered stream. 2160 * @throws IOException if an I/O error occurs 2161 * @since 2.5 2162 */ 2163 public static InputStream toBufferedInputStream(final InputStream input, final int size) throws IOException { 2164 return ByteArrayOutputStream.toBufferedInputStream(input, size); 2165 } 2166 2167 /** 2168 * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given 2169 * reader. 2170 * 2171 * @param reader the reader to wrap or return (not null) 2172 * @return the given reader or a new {@link BufferedReader} for the given reader 2173 * @throws NullPointerException if the input parameter is null 2174 * @see #buffer(Reader) 2175 * @since 2.2 2176 */ 2177 public static BufferedReader toBufferedReader(final Reader reader) { 2178 return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader); 2179 } 2180 2181 /** 2182 * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given 2183 * reader. 2184 * 2185 * @param reader the reader to wrap or return (not null) 2186 * @param size the buffer size, if a new BufferedReader is created. 2187 * @return the given reader or a new {@link BufferedReader} for the given reader 2188 * @throws NullPointerException if the input parameter is null 2189 * @see #buffer(Reader) 2190 * @since 2.5 2191 */ 2192 public static BufferedReader toBufferedReader(final Reader reader, final int size) { 2193 return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader, size); 2194 } 2195 2196 /** 2197 * Gets the contents of an <code>InputStream</code> as a <code>byte[]</code>. 2198 * <p> 2199 * This method buffers the input internally, so there is no need to use a 2200 * <code>BufferedInputStream</code>. 2201 * 2202 * @param input the <code>InputStream</code> to read from 2203 * @return the requested byte array 2204 * @throws NullPointerException if the input is null 2205 * @throws IOException if an I/O error occurs 2206 */ 2207 public static byte[] toByteArray(final InputStream input) throws IOException { 2208 try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) { 2209 copy(input, output); 2210 return output.toByteArray(); 2211 } 2212 } 2213 2214 /** 2215 * Gets the contents of an <code>InputStream</code> as a <code>byte[]</code>. 2216 * Use this method instead of <code>toByteArray(InputStream)</code> 2217 * when <code>InputStream</code> size is known 2218 * 2219 * @param input the <code>InputStream</code> to read from 2220 * @param size the size of <code>InputStream</code> 2221 * @return the requested byte array 2222 * @throws IOException if an I/O error occurs or <code>InputStream</code> size differ from parameter 2223 * size 2224 * @throws IllegalArgumentException if size is less than zero 2225 * @since 2.1 2226 */ 2227 public static byte[] toByteArray(final InputStream input, final int size) throws IOException { 2228 2229 if (size < 0) { 2230 throw new IllegalArgumentException("Size must be equal or greater than zero: " + size); 2231 } 2232 2233 if (size == 0) { 2234 return EMPTY_BYTE_ARRAY; 2235 } 2236 2237 final byte[] data = new byte[size]; 2238 int offset = 0; 2239 int read; 2240 2241 while (offset < size && (read = input.read(data, offset, size - offset)) != EOF) { 2242 offset += read; 2243 } 2244 2245 if (offset != size) { 2246 throw new IOException("Unexpected read size. current: " + offset + ", expected: " + size); 2247 } 2248 2249 return data; 2250 } 2251 2252 /** 2253 * Gets contents of an <code>InputStream</code> as a <code>byte[]</code>. 2254 * Use this method instead of <code>toByteArray(InputStream)</code> 2255 * when <code>InputStream</code> size is known. 2256 * <b>NOTE:</b> the method checks that the length can safely be cast to an int without truncation 2257 * before using {@link IOUtils#toByteArray(java.io.InputStream, int)} to read into the byte array. 2258 * (Arrays can have no more than Integer.MAX_VALUE entries anyway) 2259 * 2260 * @param input the <code>InputStream</code> to read from 2261 * @param size the size of <code>InputStream</code> 2262 * @return the requested byte array 2263 * @throws IOException if an I/O error occurs or <code>InputStream</code> size differ from parameter 2264 * size 2265 * @throws IllegalArgumentException if size is less than zero or size is greater than Integer.MAX_VALUE 2266 * @see IOUtils#toByteArray(java.io.InputStream, int) 2267 * @since 2.1 2268 */ 2269 public static byte[] toByteArray(final InputStream input, final long size) throws IOException { 2270 2271 if (size > Integer.MAX_VALUE) { 2272 throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size); 2273 } 2274 2275 return toByteArray(input, (int) size); 2276 } 2277 2278 /** 2279 * Gets the contents of a <code>Reader</code> as a <code>byte[]</code> 2280 * using the default character encoding of the platform. 2281 * <p> 2282 * This method buffers the input internally, so there is no need to use a 2283 * <code>BufferedReader</code>. 2284 * 2285 * @param input the <code>Reader</code> to read from 2286 * @return the requested byte array 2287 * @throws NullPointerException if the input is null 2288 * @throws IOException if an I/O error occurs 2289 * @deprecated 2.5 use {@link #toByteArray(Reader, Charset)} instead 2290 */ 2291 @Deprecated 2292 public static byte[] toByteArray(final Reader input) throws IOException { 2293 return toByteArray(input, Charset.defaultCharset()); 2294 } 2295 2296 /** 2297 * Gets the contents of a <code>Reader</code> as a <code>byte[]</code> 2298 * using the specified character encoding. 2299 * <p> 2300 * This method buffers the input internally, so there is no need to use a 2301 * <code>BufferedReader</code>. 2302 * 2303 * @param input the <code>Reader</code> to read from 2304 * @param charset the charset to use, null means platform default 2305 * @return the requested byte array 2306 * @throws NullPointerException if the input is null 2307 * @throws IOException if an I/O error occurs 2308 * @since 2.3 2309 */ 2310 public static byte[] toByteArray(final Reader input, final Charset charset) throws IOException { 2311 try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) { 2312 copy(input, output, charset); 2313 return output.toByteArray(); 2314 } 2315 } 2316 2317 /** 2318 * Gets the contents of a <code>Reader</code> as a <code>byte[]</code> 2319 * using the specified character encoding. 2320 * <p> 2321 * Character encoding names can be found at 2322 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 2323 * <p> 2324 * This method buffers the input internally, so there is no need to use a 2325 * <code>BufferedReader</code>. 2326 * 2327 * @param input the <code>Reader</code> to read from 2328 * @param charsetName the name of the requested charset, null means platform default 2329 * @return the requested byte array 2330 * @throws NullPointerException if the input is null 2331 * @throws IOException if an I/O error occurs 2332 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 2333 * .UnsupportedEncodingException} in version 2.2 if the 2334 * encoding is not supported. 2335 * @since 1.1 2336 */ 2337 public static byte[] toByteArray(final Reader input, final String charsetName) throws IOException { 2338 return toByteArray(input, Charsets.toCharset(charsetName)); 2339 } 2340 2341 /** 2342 * Gets the contents of a <code>String</code> as a <code>byte[]</code> 2343 * using the default character encoding of the platform. 2344 * <p> 2345 * This is the same as {@link String#getBytes()}. 2346 * 2347 * @param input the <code>String</code> to convert 2348 * @return the requested byte array 2349 * @throws NullPointerException if the input is null 2350 * @throws IOException if an I/O error occurs (never occurs) 2351 * @deprecated 2.5 Use {@link String#getBytes()} instead 2352 */ 2353 @Deprecated 2354 public static byte[] toByteArray(final String input) throws IOException { 2355 // make explicit the use of the default charset 2356 return input.getBytes(Charset.defaultCharset()); 2357 } 2358 2359 /** 2360 * Gets the contents of a <code>URI</code> as a <code>byte[]</code>. 2361 * 2362 * @param uri the <code>URI</code> to read 2363 * @return the requested byte array 2364 * @throws NullPointerException if the uri is null 2365 * @throws IOException if an I/O exception occurs 2366 * @since 2.4 2367 */ 2368 public static byte[] toByteArray(final URI uri) throws IOException { 2369 return IOUtils.toByteArray(uri.toURL()); 2370 } 2371 2372 /** 2373 * Gets the contents of a <code>URL</code> as a <code>byte[]</code>. 2374 * 2375 * @param url the <code>URL</code> to read 2376 * @return the requested byte array 2377 * @throws NullPointerException if the input is null 2378 * @throws IOException if an I/O exception occurs 2379 * @since 2.4 2380 */ 2381 public static byte[] toByteArray(final URL url) throws IOException { 2382 final URLConnection conn = url.openConnection(); 2383 try { 2384 return IOUtils.toByteArray(conn); 2385 } finally { 2386 close(conn); 2387 } 2388 } 2389 2390 /** 2391 * Gets the contents of a <code>URLConnection</code> as a <code>byte[]</code>. 2392 * 2393 * @param urlConn the <code>URLConnection</code> to read 2394 * @return the requested byte array 2395 * @throws NullPointerException if the urlConn is null 2396 * @throws IOException if an I/O exception occurs 2397 * @since 2.4 2398 */ 2399 public static byte[] toByteArray(final URLConnection urlConn) throws IOException { 2400 try (InputStream inputStream = urlConn.getInputStream()) { 2401 return IOUtils.toByteArray(inputStream); 2402 } 2403 } 2404 2405 /** 2406 * Gets the contents of an <code>InputStream</code> as a character array 2407 * using the default character encoding of the platform. 2408 * <p> 2409 * This method buffers the input internally, so there is no need to use a 2410 * <code>BufferedInputStream</code>. 2411 * 2412 * @param is the <code>InputStream</code> to read from 2413 * @return the requested character array 2414 * @throws NullPointerException if the input is null 2415 * @throws IOException if an I/O error occurs 2416 * @since 1.1 2417 * @deprecated 2.5 use {@link #toCharArray(InputStream, Charset)} instead 2418 */ 2419 @Deprecated 2420 public static char[] toCharArray(final InputStream is) throws IOException { 2421 return toCharArray(is, Charset.defaultCharset()); 2422 } 2423 2424 /** 2425 * Gets the contents of an <code>InputStream</code> as a character array 2426 * using the specified character encoding. 2427 * <p> 2428 * This method buffers the input internally, so there is no need to use a 2429 * <code>BufferedInputStream</code>. 2430 * 2431 * @param is the <code>InputStream</code> to read from 2432 * @param charset the charset to use, null means platform default 2433 * @return the requested character array 2434 * @throws NullPointerException if the input is null 2435 * @throws IOException if an I/O error occurs 2436 * @since 2.3 2437 */ 2438 public static char[] toCharArray(final InputStream is, final Charset charset) 2439 throws IOException { 2440 final CharArrayWriter output = new CharArrayWriter(); 2441 copy(is, output, charset); 2442 return output.toCharArray(); 2443 } 2444 2445 /** 2446 * Gets the contents of an <code>InputStream</code> as a character array 2447 * using the specified character encoding. 2448 * <p> 2449 * Character encoding names can be found at 2450 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 2451 * <p> 2452 * This method buffers the input internally, so there is no need to use a 2453 * <code>BufferedInputStream</code>. 2454 * 2455 * @param is the <code>InputStream</code> to read from 2456 * @param charsetName the name of the requested charset, null means platform default 2457 * @return the requested character array 2458 * @throws NullPointerException if the input is null 2459 * @throws IOException if an I/O error occurs 2460 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 2461 * .UnsupportedEncodingException} in version 2.2 if the 2462 * encoding is not supported. 2463 * @since 1.1 2464 */ 2465 public static char[] toCharArray(final InputStream is, final String charsetName) throws IOException { 2466 return toCharArray(is, Charsets.toCharset(charsetName)); 2467 } 2468 2469 /** 2470 * Gets the contents of a <code>Reader</code> as a character array. 2471 * <p> 2472 * This method buffers the input internally, so there is no need to use a 2473 * <code>BufferedReader</code>. 2474 * 2475 * @param input the <code>Reader</code> to read from 2476 * @return the requested character array 2477 * @throws NullPointerException if the input is null 2478 * @throws IOException if an I/O error occurs 2479 * @since 1.1 2480 */ 2481 public static char[] toCharArray(final Reader input) throws IOException { 2482 final CharArrayWriter sw = new CharArrayWriter(); 2483 copy(input, sw); 2484 return sw.toCharArray(); 2485 } 2486 2487 /** 2488 * Converts the specified CharSequence to an input stream, encoded as bytes 2489 * using the default character encoding of the platform. 2490 * 2491 * @param input the CharSequence to convert 2492 * @return an input stream 2493 * @since 2.0 2494 * @deprecated 2.5 use {@link #toInputStream(CharSequence, Charset)} instead 2495 */ 2496 @Deprecated 2497 public static InputStream toInputStream(final CharSequence input) { 2498 return toInputStream(input, Charset.defaultCharset()); 2499 } 2500 2501 /** 2502 * Converts the specified CharSequence to an input stream, encoded as bytes 2503 * using the specified character encoding. 2504 * 2505 * @param input the CharSequence to convert 2506 * @param charset the charset to use, null means platform default 2507 * @return an input stream 2508 * @since 2.3 2509 */ 2510 public static InputStream toInputStream(final CharSequence input, final Charset charset) { 2511 return toInputStream(input.toString(), charset); 2512 } 2513 2514 /** 2515 * Converts the specified CharSequence to an input stream, encoded as bytes 2516 * using the specified character encoding. 2517 * <p> 2518 * Character encoding names can be found at 2519 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 2520 * 2521 * @param input the CharSequence to convert 2522 * @param charsetName the name of the requested charset, null means platform default 2523 * @return an input stream 2524 * @throws IOException if the encoding is invalid 2525 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 2526 * .UnsupportedEncodingException} in version 2.2 if the 2527 * encoding is not supported. 2528 * @since 2.0 2529 */ 2530 public static InputStream toInputStream(final CharSequence input, final String charsetName) throws IOException { 2531 return toInputStream(input, Charsets.toCharset(charsetName)); 2532 } 2533 2534 /** 2535 * Converts the specified string to an input stream, encoded as bytes 2536 * using the default character encoding of the platform. 2537 * 2538 * @param input the string to convert 2539 * @return an input stream 2540 * @since 1.1 2541 * @deprecated 2.5 use {@link #toInputStream(String, Charset)} instead 2542 */ 2543 @Deprecated 2544 public static InputStream toInputStream(final String input) { 2545 return toInputStream(input, Charset.defaultCharset()); 2546 } 2547 2548 /** 2549 * Converts the specified string to an input stream, encoded as bytes 2550 * using the specified character encoding. 2551 * 2552 * @param input the string to convert 2553 * @param charset the charset to use, null means platform default 2554 * @return an input stream 2555 * @since 2.3 2556 */ 2557 public static InputStream toInputStream(final String input, final Charset charset) { 2558 return new ByteArrayInputStream(input.getBytes(Charsets.toCharset(charset))); 2559 } 2560 2561 /** 2562 * Converts the specified string to an input stream, encoded as bytes 2563 * using the specified character encoding. 2564 * <p> 2565 * Character encoding names can be found at 2566 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 2567 * 2568 * @param input the string to convert 2569 * @param charsetName the name of the requested charset, null means platform default 2570 * @return an input stream 2571 * @throws IOException if the encoding is invalid 2572 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 2573 * .UnsupportedEncodingException} in version 2.2 if the 2574 * encoding is not supported. 2575 * @since 1.1 2576 */ 2577 public static InputStream toInputStream(final String input, final String charsetName) throws IOException { 2578 final byte[] bytes = input.getBytes(Charsets.toCharset(charsetName)); 2579 return new ByteArrayInputStream(bytes); 2580 } 2581 2582 /** 2583 * Gets the contents of a <code>byte[]</code> as a String 2584 * using the default character encoding of the platform. 2585 * 2586 * @param input the byte array to read from 2587 * @return the requested String 2588 * @throws NullPointerException if the input is null 2589 * @throws IOException if an I/O error occurs (never occurs) 2590 * @deprecated 2.5 Use {@link String#String(byte[])} instead 2591 */ 2592 @Deprecated 2593 public static String toString(final byte[] input) throws IOException { 2594 // make explicit the use of the default charset 2595 return new String(input, Charset.defaultCharset()); 2596 } 2597 2598 /** 2599 * Gets the contents of a <code>byte[]</code> as a String 2600 * using the specified character encoding. 2601 * <p> 2602 * Character encoding names can be found at 2603 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 2604 * 2605 * @param input the byte array to read from 2606 * @param charsetName the name of the requested charset, null means platform default 2607 * @return the requested String 2608 * @throws NullPointerException if the input is null 2609 * @throws IOException if an I/O error occurs (never occurs) 2610 */ 2611 public static String toString(final byte[] input, final String charsetName) throws IOException { 2612 return new String(input, Charsets.toCharset(charsetName)); 2613 } 2614 2615 /** 2616 * Gets the contents of an <code>InputStream</code> as a String 2617 * using the default character encoding of the platform. 2618 * <p> 2619 * This method buffers the input internally, so there is no need to use a 2620 * <code>BufferedInputStream</code>. 2621 * 2622 * @param input the <code>InputStream</code> to read from 2623 * @return the requested String 2624 * @throws NullPointerException if the input is null 2625 * @throws IOException if an I/O error occurs 2626 * @deprecated 2.5 use {@link #toString(InputStream, Charset)} instead 2627 */ 2628 @Deprecated 2629 public static String toString(final InputStream input) throws IOException { 2630 return toString(input, Charset.defaultCharset()); 2631 } 2632 2633 /** 2634 * Gets the contents of an <code>InputStream</code> as a String 2635 * using the specified character encoding. 2636 * <p> 2637 * This method buffers the input internally, so there is no need to use a 2638 * <code>BufferedInputStream</code>. 2639 * </p> 2640 * 2641 * @param input the <code>InputStream</code> to read from 2642 * @param charset the charset to use, null means platform default 2643 * @return the requested String 2644 * @throws NullPointerException if the input is null 2645 * @throws IOException if an I/O error occurs 2646 * @since 2.3 2647 */ 2648 public static String toString(final InputStream input, final Charset charset) throws IOException { 2649 try (final StringBuilderWriter sw = new StringBuilderWriter()) { 2650 copy(input, sw, charset); 2651 return sw.toString(); 2652 } 2653 } 2654 2655 /** 2656 * Gets the contents of an <code>InputStream</code> as a String 2657 * using the specified character encoding. 2658 * <p> 2659 * Character encoding names can be found at 2660 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 2661 * <p> 2662 * This method buffers the input internally, so there is no need to use a 2663 * <code>BufferedInputStream</code>. 2664 * 2665 * @param input the <code>InputStream</code> to read from 2666 * @param charsetName the name of the requested charset, null means platform default 2667 * @return the requested String 2668 * @throws NullPointerException if the input is null 2669 * @throws IOException if an I/O error occurs 2670 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 2671 * .UnsupportedEncodingException} in version 2.2 if the 2672 * encoding is not supported. 2673 */ 2674 public static String toString(final InputStream input, final String charsetName) 2675 throws IOException { 2676 return toString(input, Charsets.toCharset(charsetName)); 2677 } 2678 2679 /** 2680 * Gets the contents of a <code>Reader</code> as a String. 2681 * <p> 2682 * This method buffers the input internally, so there is no need to use a 2683 * <code>BufferedReader</code>. 2684 * 2685 * @param input the <code>Reader</code> to read from 2686 * @return the requested String 2687 * @throws NullPointerException if the input is null 2688 * @throws IOException if an I/O error occurs 2689 */ 2690 public static String toString(final Reader input) throws IOException { 2691 try (final StringBuilderWriter sw = new StringBuilderWriter()) { 2692 copy(input, sw); 2693 return sw.toString(); 2694 } 2695 } 2696 2697 /** 2698 * Gets the contents at the given URI. 2699 * 2700 * @param uri The URI source. 2701 * @return The contents of the URL as a String. 2702 * @throws IOException if an I/O exception occurs. 2703 * @since 2.1 2704 * @deprecated 2.5 use {@link #toString(URI, Charset)} instead 2705 */ 2706 @Deprecated 2707 public static String toString(final URI uri) throws IOException { 2708 return toString(uri, Charset.defaultCharset()); 2709 } 2710 2711 /** 2712 * Gets the contents at the given URI. 2713 * 2714 * @param uri The URI source. 2715 * @param encoding The encoding name for the URL contents. 2716 * @return The contents of the URL as a String. 2717 * @throws IOException if an I/O exception occurs. 2718 * @since 2.3. 2719 */ 2720 public static String toString(final URI uri, final Charset encoding) throws IOException { 2721 return toString(uri.toURL(), Charsets.toCharset(encoding)); 2722 } 2723 2724 /** 2725 * Gets the contents at the given URI. 2726 * 2727 * @param uri The URI source. 2728 * @param charsetName The encoding name for the URL contents. 2729 * @return The contents of the URL as a String. 2730 * @throws IOException if an I/O exception occurs. 2731 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 2732 * .UnsupportedEncodingException} in version 2.2 if the 2733 * encoding is not supported. 2734 * @since 2.1 2735 */ 2736 public static String toString(final URI uri, final String charsetName) throws IOException { 2737 return toString(uri, Charsets.toCharset(charsetName)); 2738 } 2739 2740 /** 2741 * Gets the contents at the given URL. 2742 * 2743 * @param url The URL source. 2744 * @return The contents of the URL as a String. 2745 * @throws IOException if an I/O exception occurs. 2746 * @since 2.1 2747 * @deprecated 2.5 use {@link #toString(URL, Charset)} instead 2748 */ 2749 @Deprecated 2750 public static String toString(final URL url) throws IOException { 2751 return toString(url, Charset.defaultCharset()); 2752 } 2753 2754 /** 2755 * Gets the contents at the given URL. 2756 * 2757 * @param url The URL source. 2758 * @param encoding The encoding name for the URL contents. 2759 * @return The contents of the URL as a String. 2760 * @throws IOException if an I/O exception occurs. 2761 * @since 2.3 2762 */ 2763 public static String toString(final URL url, final Charset encoding) throws IOException { 2764 try (InputStream inputStream = url.openStream()) { 2765 return toString(inputStream, encoding); 2766 } 2767 } 2768 2769 /** 2770 * Gets the contents at the given URL. 2771 * 2772 * @param url The URL source. 2773 * @param charsetName The encoding name for the URL contents. 2774 * @return The contents of the URL as a String. 2775 * @throws IOException if an I/O exception occurs. 2776 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 2777 * .UnsupportedEncodingException} in version 2.2 if the 2778 * encoding is not supported. 2779 * @since 2.1 2780 */ 2781 public static String toString(final URL url, final String charsetName) throws IOException { 2782 return toString(url, Charsets.toCharset(charsetName)); 2783 } 2784 2785 /** 2786 * Writes bytes from a <code>byte[]</code> to an <code>OutputStream</code>. 2787 * 2788 * @param data the byte array to write, do not modify during output, 2789 * null ignored 2790 * @param output the <code>OutputStream</code> to write to 2791 * @throws NullPointerException if output is null 2792 * @throws IOException if an I/O error occurs 2793 * @since 1.1 2794 */ 2795 public static void write(final byte[] data, final OutputStream output) 2796 throws IOException { 2797 if (data != null) { 2798 output.write(data); 2799 } 2800 } 2801 2802 /** 2803 * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code> 2804 * using the default character encoding of the platform. 2805 * <p> 2806 * This method uses {@link String#String(byte[])}. 2807 * 2808 * @param data the byte array to write, do not modify during output, 2809 * null ignored 2810 * @param output the <code>Writer</code> to write to 2811 * @throws NullPointerException if output is null 2812 * @throws IOException if an I/O error occurs 2813 * @since 1.1 2814 * @deprecated 2.5 use {@link #write(byte[], Writer, Charset)} instead 2815 */ 2816 @Deprecated 2817 public static void write(final byte[] data, final Writer output) throws IOException { 2818 write(data, output, Charset.defaultCharset()); 2819 } 2820 2821 /** 2822 * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code> 2823 * using the specified character encoding. 2824 * <p> 2825 * This method uses {@link String#String(byte[], String)}. 2826 * 2827 * @param data the byte array to write, do not modify during output, 2828 * null ignored 2829 * @param output the <code>Writer</code> to write to 2830 * @param charset the charset to use, null means platform default 2831 * @throws NullPointerException if output is null 2832 * @throws IOException if an I/O error occurs 2833 * @since 2.3 2834 */ 2835 public static void write(final byte[] data, final Writer output, final Charset charset) throws IOException { 2836 if (data != null) { 2837 output.write(new String(data, Charsets.toCharset(charset))); 2838 } 2839 } 2840 2841 /** 2842 * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code> 2843 * using the specified character encoding. 2844 * <p> 2845 * Character encoding names can be found at 2846 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 2847 * <p> 2848 * This method uses {@link String#String(byte[], String)}. 2849 * 2850 * @param data the byte array to write, do not modify during output, 2851 * null ignored 2852 * @param output the <code>Writer</code> to write to 2853 * @param charsetName the name of the requested charset, null means platform default 2854 * @throws NullPointerException if output is null 2855 * @throws IOException if an I/O error occurs 2856 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 2857 * .UnsupportedEncodingException} in version 2.2 if the 2858 * encoding is not supported. 2859 * @since 1.1 2860 */ 2861 public static void write(final byte[] data, final Writer output, final String charsetName) throws IOException { 2862 write(data, output, Charsets.toCharset(charsetName)); 2863 } 2864 2865 /** 2866 * Writes chars from a <code>char[]</code> to bytes on an 2867 * <code>OutputStream</code>. 2868 * <p> 2869 * This method uses {@link String#String(char[])} and 2870 * {@link String#getBytes()}. 2871 * 2872 * @param data the char array to write, do not modify during output, 2873 * null ignored 2874 * @param output the <code>OutputStream</code> to write to 2875 * @throws NullPointerException if output is null 2876 * @throws IOException if an I/O error occurs 2877 * @since 1.1 2878 * @deprecated 2.5 use {@link #write(char[], OutputStream, Charset)} instead 2879 */ 2880 @Deprecated 2881 public static void write(final char[] data, final OutputStream output) 2882 throws IOException { 2883 write(data, output, Charset.defaultCharset()); 2884 } 2885 2886 /** 2887 * Writes chars from a <code>char[]</code> to bytes on an 2888 * <code>OutputStream</code> using the specified character encoding. 2889 * <p> 2890 * This method uses {@link String#String(char[])} and 2891 * {@link String#getBytes(String)}. 2892 * 2893 * @param data the char array to write, do not modify during output, 2894 * null ignored 2895 * @param output the <code>OutputStream</code> to write to 2896 * @param charset the chartset to use, null means platform default 2897 * @throws NullPointerException if output is null 2898 * @throws IOException if an I/O error occurs 2899 * @since 2.3 2900 */ 2901 public static void write(final char[] data, final OutputStream output, final Charset charset) throws IOException { 2902 if (data != null) { 2903 output.write(new String(data).getBytes(Charsets.toCharset(charset))); 2904 } 2905 } 2906 2907 /** 2908 * Writes chars from a <code>char[]</code> to bytes on an 2909 * <code>OutputStream</code> using the specified character encoding. 2910 * <p> 2911 * Character encoding names can be found at 2912 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 2913 * <p> 2914 * This method uses {@link String#String(char[])} and 2915 * {@link String#getBytes(String)}. 2916 * 2917 * @param data the char array to write, do not modify during output, 2918 * null ignored 2919 * @param output the <code>OutputStream</code> to write to 2920 * @param charsetName the name of the requested charset, null means platform default 2921 * @throws NullPointerException if output is null 2922 * @throws IOException if an I/O error occurs 2923 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 2924 * .UnsupportedEncodingException} in version 2.2 if the encoding is not supported. 2925 * @since 1.1 2926 */ 2927 public static void write(final char[] data, final OutputStream output, final String charsetName) 2928 throws IOException { 2929 write(data, output, Charsets.toCharset(charsetName)); 2930 } 2931 2932 /** 2933 * Writes chars from a <code>char[]</code> to a <code>Writer</code> 2934 * 2935 * @param data the char array to write, do not modify during output, 2936 * null ignored 2937 * @param output the <code>Writer</code> to write to 2938 * @throws NullPointerException if output is null 2939 * @throws IOException if an I/O error occurs 2940 * @since 1.1 2941 */ 2942 public static void write(final char[] data, final Writer output) throws IOException { 2943 if (data != null) { 2944 output.write(data); 2945 } 2946 } 2947 2948 /** 2949 * Writes chars from a <code>CharSequence</code> to bytes on an 2950 * <code>OutputStream</code> using the default character encoding of the 2951 * platform. 2952 * <p> 2953 * This method uses {@link String#getBytes()}. 2954 * 2955 * @param data the <code>CharSequence</code> to write, null ignored 2956 * @param output the <code>OutputStream</code> to write to 2957 * @throws NullPointerException if output is null 2958 * @throws IOException if an I/O error occurs 2959 * @since 2.0 2960 * @deprecated 2.5 use {@link #write(CharSequence, OutputStream, Charset)} instead 2961 */ 2962 @Deprecated 2963 public static void write(final CharSequence data, final OutputStream output) 2964 throws IOException { 2965 write(data, output, Charset.defaultCharset()); 2966 } 2967 2968 /** 2969 * Writes chars from a <code>CharSequence</code> to bytes on an 2970 * <code>OutputStream</code> using the specified character encoding. 2971 * <p> 2972 * This method uses {@link String#getBytes(String)}. 2973 * 2974 * @param data the <code>CharSequence</code> to write, null ignored 2975 * @param output the <code>OutputStream</code> to write to 2976 * @param charset the charset to use, null means platform default 2977 * @throws NullPointerException if output is null 2978 * @throws IOException if an I/O error occurs 2979 * @since 2.3 2980 */ 2981 public static void write(final CharSequence data, final OutputStream output, final Charset charset) 2982 throws IOException { 2983 if (data != null) { 2984 write(data.toString(), output, charset); 2985 } 2986 } 2987 2988 /** 2989 * Writes chars from a <code>CharSequence</code> to bytes on an 2990 * <code>OutputStream</code> using the specified character encoding. 2991 * <p> 2992 * Character encoding names can be found at 2993 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 2994 * <p> 2995 * This method uses {@link String#getBytes(String)}. 2996 * 2997 * @param data the <code>CharSequence</code> to write, null ignored 2998 * @param output the <code>OutputStream</code> to write to 2999 * @param charsetName the name of the requested charset, null means platform default 3000 * @throws NullPointerException if output is null 3001 * @throws IOException if an I/O error occurs 3002 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 3003 * .UnsupportedEncodingException} in version 2.2 if the encoding is not supported. 3004 * @since 2.0 3005 */ 3006 public static void write(final CharSequence data, final OutputStream output, final String charsetName) 3007 throws IOException { 3008 write(data, output, Charsets.toCharset(charsetName)); 3009 } 3010 3011 /** 3012 * Writes chars from a <code>CharSequence</code> to a <code>Writer</code>. 3013 * 3014 * @param data the <code>CharSequence</code> to write, null ignored 3015 * @param output the <code>Writer</code> to write to 3016 * @throws NullPointerException if output is null 3017 * @throws IOException if an I/O error occurs 3018 * @since 2.0 3019 */ 3020 public static void write(final CharSequence data, final Writer output) throws IOException { 3021 if (data != null) { 3022 write(data.toString(), output); 3023 } 3024 } 3025 3026 3027 /** 3028 * Writes chars from a <code>String</code> to bytes on an 3029 * <code>OutputStream</code> using the default character encoding of the 3030 * platform. 3031 * <p> 3032 * This method uses {@link String#getBytes()}. 3033 * 3034 * @param data the <code>String</code> to write, null ignored 3035 * @param output the <code>OutputStream</code> to write to 3036 * @throws NullPointerException if output is null 3037 * @throws IOException if an I/O error occurs 3038 * @since 1.1 3039 * @deprecated 2.5 use {@link #write(String, OutputStream, Charset)} instead 3040 */ 3041 @Deprecated 3042 public static void write(final String data, final OutputStream output) 3043 throws IOException { 3044 write(data, output, Charset.defaultCharset()); 3045 } 3046 3047 /** 3048 * Writes chars from a <code>String</code> to bytes on an 3049 * <code>OutputStream</code> using the specified character encoding. 3050 * <p> 3051 * This method uses {@link String#getBytes(String)}. 3052 * 3053 * @param data the <code>String</code> to write, null ignored 3054 * @param output the <code>OutputStream</code> to write to 3055 * @param charset the charset to use, null means platform default 3056 * @throws NullPointerException if output is null 3057 * @throws IOException if an I/O error occurs 3058 * @since 2.3 3059 */ 3060 public static void write(final String data, final OutputStream output, final Charset charset) throws IOException { 3061 if (data != null) { 3062 output.write(data.getBytes(Charsets.toCharset(charset))); 3063 } 3064 } 3065 3066 /** 3067 * Writes chars from a <code>String</code> to bytes on an 3068 * <code>OutputStream</code> using the specified character encoding. 3069 * <p> 3070 * Character encoding names can be found at 3071 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 3072 * <p> 3073 * This method uses {@link String#getBytes(String)}. 3074 * 3075 * @param data the <code>String</code> to write, null ignored 3076 * @param output the <code>OutputStream</code> to write to 3077 * @param charsetName the name of the requested charset, null means platform default 3078 * @throws NullPointerException if output is null 3079 * @throws IOException if an I/O error occurs 3080 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 3081 * .UnsupportedEncodingException} in version 2.2 if the encoding is not supported. 3082 * @since 1.1 3083 */ 3084 public static void write(final String data, final OutputStream output, final String charsetName) 3085 throws IOException { 3086 write(data, output, Charsets.toCharset(charsetName)); 3087 } 3088 3089 /** 3090 * Writes chars from a <code>String</code> to a <code>Writer</code>. 3091 * 3092 * @param data the <code>String</code> to write, null ignored 3093 * @param output the <code>Writer</code> to write to 3094 * @throws NullPointerException if output is null 3095 * @throws IOException if an I/O error occurs 3096 * @since 1.1 3097 */ 3098 public static void write(final String data, final Writer output) throws IOException { 3099 if (data != null) { 3100 output.write(data); 3101 } 3102 } 3103 3104 /** 3105 * Writes chars from a <code>StringBuffer</code> to bytes on an 3106 * <code>OutputStream</code> using the default character encoding of the 3107 * platform. 3108 * <p> 3109 * This method uses {@link String#getBytes()}. 3110 * 3111 * @param data the <code>StringBuffer</code> to write, null ignored 3112 * @param output the <code>OutputStream</code> to write to 3113 * @throws NullPointerException if output is null 3114 * @throws IOException if an I/O error occurs 3115 * @since 1.1 3116 * @deprecated replaced by write(CharSequence, OutputStream) 3117 */ 3118 @Deprecated 3119 public static void write(final StringBuffer data, final OutputStream output) 3120 throws IOException { 3121 write(data, output, (String) null); 3122 } 3123 3124 /** 3125 * Writes chars from a <code>StringBuffer</code> to bytes on an 3126 * <code>OutputStream</code> using the specified character encoding. 3127 * <p> 3128 * Character encoding names can be found at 3129 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 3130 * <p> 3131 * This method uses {@link String#getBytes(String)}. 3132 * 3133 * @param data the <code>StringBuffer</code> to write, null ignored 3134 * @param output the <code>OutputStream</code> to write to 3135 * @param charsetName the name of the requested charset, null means platform default 3136 * @throws NullPointerException if output is null 3137 * @throws IOException if an I/O error occurs 3138 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 3139 * .UnsupportedEncodingException} in version 2.2 if the encoding is not supported. 3140 * @since 1.1 3141 * @deprecated replaced by write(CharSequence, OutputStream, String) 3142 */ 3143 @Deprecated 3144 public static void write(final StringBuffer data, final OutputStream output, final String charsetName) 3145 throws IOException { 3146 if (data != null) { 3147 output.write(data.toString().getBytes(Charsets.toCharset(charsetName))); 3148 } 3149 } 3150 3151 /** 3152 * Writes chars from a <code>StringBuffer</code> to a <code>Writer</code>. 3153 * 3154 * @param data the <code>StringBuffer</code> to write, null ignored 3155 * @param output the <code>Writer</code> to write to 3156 * @throws NullPointerException if output is null 3157 * @throws IOException if an I/O error occurs 3158 * @since 1.1 3159 * @deprecated replaced by write(CharSequence, Writer) 3160 */ 3161 @Deprecated 3162 public static void write(final StringBuffer data, final Writer output) 3163 throws IOException { 3164 if (data != null) { 3165 output.write(data.toString()); 3166 } 3167 } 3168 3169 /** 3170 * Writes bytes from a <code>byte[]</code> to an <code>OutputStream</code> using chunked writes. 3171 * This is intended for writing very large byte arrays which might otherwise cause excessive 3172 * memory usage if the native code has to allocate a copy. 3173 * 3174 * @param data the byte array to write, do not modify during output, 3175 * null ignored 3176 * @param output the <code>OutputStream</code> to write to 3177 * @throws NullPointerException if output is null 3178 * @throws IOException if an I/O error occurs 3179 * @since 2.5 3180 */ 3181 public static void writeChunked(final byte[] data, final OutputStream output) 3182 throws IOException { 3183 if (data != null) { 3184 int bytes = data.length; 3185 int offset = 0; 3186 while (bytes > 0) { 3187 final int chunk = Math.min(bytes, DEFAULT_BUFFER_SIZE); 3188 output.write(data, offset, chunk); 3189 bytes -= chunk; 3190 offset += chunk; 3191 } 3192 } 3193 } 3194 3195 /** 3196 * Writes chars from a <code>char[]</code> to a <code>Writer</code> using chunked writes. 3197 * This is intended for writing very large byte arrays which might otherwise cause excessive 3198 * memory usage if the native code has to allocate a copy. 3199 * 3200 * @param data the char array to write, do not modify during output, 3201 * null ignored 3202 * @param output the <code>Writer</code> to write to 3203 * @throws NullPointerException if output is null 3204 * @throws IOException if an I/O error occurs 3205 * @since 2.5 3206 */ 3207 public static void writeChunked(final char[] data, final Writer output) throws IOException { 3208 if (data != null) { 3209 int bytes = data.length; 3210 int offset = 0; 3211 while (bytes > 0) { 3212 final int chunk = Math.min(bytes, DEFAULT_BUFFER_SIZE); 3213 output.write(data, offset, chunk); 3214 bytes -= chunk; 3215 offset += chunk; 3216 } 3217 } 3218 } 3219 3220 /** 3221 * Writes the <code>toString()</code> value of each item in a collection to 3222 * an <code>OutputStream</code> line by line, using the default character 3223 * encoding of the platform and the specified line ending. 3224 * 3225 * @param lines the lines to write, null entries produce blank lines 3226 * @param lineEnding the line separator to use, null is system default 3227 * @param output the <code>OutputStream</code> to write to, not null, not closed 3228 * @throws NullPointerException if the output is null 3229 * @throws IOException if an I/O error occurs 3230 * @since 1.1 3231 * @deprecated 2.5 use {@link #writeLines(Collection, String, OutputStream, Charset)} instead 3232 */ 3233 @Deprecated 3234 public static void writeLines(final Collection<?> lines, final String lineEnding, 3235 final OutputStream output) throws IOException { 3236 writeLines(lines, lineEnding, output, Charset.defaultCharset()); 3237 } 3238 3239 /** 3240 * Writes the <code>toString()</code> value of each item in a collection to 3241 * an <code>OutputStream</code> line by line, using the specified character 3242 * encoding and the specified line ending. 3243 * 3244 * @param lines the lines to write, null entries produce blank lines 3245 * @param lineEnding the line separator to use, null is system default 3246 * @param output the <code>OutputStream</code> to write to, not null, not closed 3247 * @param charset the charset to use, null means platform default 3248 * @throws NullPointerException if the output is null 3249 * @throws IOException if an I/O error occurs 3250 * @since 2.3 3251 */ 3252 public static void writeLines(final Collection<?> lines, String lineEnding, final OutputStream output, 3253 final Charset charset) throws IOException { 3254 if (lines == null) { 3255 return; 3256 } 3257 if (lineEnding == null) { 3258 lineEnding = LINE_SEPARATOR; 3259 } 3260 final Charset cs = Charsets.toCharset(charset); 3261 for (final Object line : lines) { 3262 if (line != null) { 3263 output.write(line.toString().getBytes(cs)); 3264 } 3265 output.write(lineEnding.getBytes(cs)); 3266 } 3267 } 3268 3269 /** 3270 * Writes the <code>toString()</code> value of each item in a collection to 3271 * an <code>OutputStream</code> line by line, using the specified character 3272 * encoding and the specified line ending. 3273 * <p> 3274 * Character encoding names can be found at 3275 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 3276 * 3277 * @param lines the lines to write, null entries produce blank lines 3278 * @param lineEnding the line separator to use, null is system default 3279 * @param output the <code>OutputStream</code> to write to, not null, not closed 3280 * @param charsetName the name of the requested charset, null means platform default 3281 * @throws NullPointerException if the output is null 3282 * @throws IOException if an I/O error occurs 3283 * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io 3284 * .UnsupportedEncodingException} in version 2.2 if the 3285 * encoding is not supported. 3286 * @since 1.1 3287 */ 3288 public static void writeLines(final Collection<?> lines, final String lineEnding, 3289 final OutputStream output, final String charsetName) throws IOException { 3290 writeLines(lines, lineEnding, output, Charsets.toCharset(charsetName)); 3291 } 3292 3293 /** 3294 * Writes the <code>toString()</code> value of each item in a collection to 3295 * a <code>Writer</code> line by line, using the specified line ending. 3296 * 3297 * @param lines the lines to write, null entries produce blank lines 3298 * @param lineEnding the line separator to use, null is system default 3299 * @param writer the <code>Writer</code> to write to, not null, not closed 3300 * @throws NullPointerException if the input is null 3301 * @throws IOException if an I/O error occurs 3302 * @since 1.1 3303 */ 3304 public static void writeLines(final Collection<?> lines, String lineEnding, 3305 final Writer writer) throws IOException { 3306 if (lines == null) { 3307 return; 3308 } 3309 if (lineEnding == null) { 3310 lineEnding = LINE_SEPARATOR; 3311 } 3312 for (final Object line : lines) { 3313 if (line != null) { 3314 writer.write(line.toString()); 3315 } 3316 writer.write(lineEnding); 3317 } 3318 } 3319 3320 /** 3321 * Returns the given Appendable if it is already a {@link Writer}, otherwise creates a Writer wrapper around the 3322 * given Appendable. 3323 * 3324 * @param appendable the Appendable to wrap or return (not null) 3325 * @return the given Appendable or a Writer wrapper around the given Appendable 3326 * @throws NullPointerException if the input parameter is null 3327 * @since 2.7 3328 */ 3329 public static Writer writer(final Appendable appendable) { 3330 Objects.requireNonNull(appendable, "appendable"); 3331 if (appendable instanceof Writer) { 3332 return (Writer) appendable; 3333 } 3334 if (appendable instanceof StringBuilder) { 3335 return new StringBuilderWriter((StringBuilder) appendable); 3336 } 3337 return new AppendableWriter<>(appendable); 3338 } 3339 3340 /** 3341 * Instances should NOT be constructed in standard programming. 3342 */ 3343 public IOUtils() { 3344 super(); 3345 } 3346 3347}