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 * https://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 */ 017 018package org.apache.commons.io; 019 020import java.io.BufferedInputStream; 021import java.io.BufferedOutputStream; 022import java.io.BufferedReader; 023import java.io.BufferedWriter; 024import java.io.ByteArrayInputStream; 025import java.io.CharArrayWriter; 026import java.io.Closeable; 027import java.io.EOFException; 028import java.io.File; 029import java.io.IOException; 030import java.io.InputStream; 031import java.io.InputStreamReader; 032import java.io.OutputStream; 033import java.io.OutputStreamWriter; 034import java.io.PipedInputStream; 035import java.io.PipedOutputStream; 036import java.io.Reader; 037import java.io.UncheckedIOException; 038import java.io.Writer; 039import java.net.HttpURLConnection; 040import java.net.ServerSocket; 041import java.net.Socket; 042import java.net.URI; 043import java.net.URL; 044import java.net.URLConnection; 045import java.nio.ByteBuffer; 046import java.nio.CharBuffer; 047import java.nio.channels.Channels; 048import java.nio.channels.ReadableByteChannel; 049import java.nio.channels.Selector; 050import java.nio.charset.Charset; 051import java.nio.charset.StandardCharsets; 052import java.nio.file.Files; 053import java.util.Arrays; 054import java.util.Collection; 055import java.util.Iterator; 056import java.util.List; 057import java.util.Objects; 058import java.util.function.Consumer; 059import java.util.function.Supplier; 060import java.util.stream.Collectors; 061import java.util.stream.Stream; 062import java.util.zip.InflaterInputStream; 063 064import org.apache.commons.io.channels.FileChannels; 065import org.apache.commons.io.function.IOConsumer; 066import org.apache.commons.io.function.IOSupplier; 067import org.apache.commons.io.function.IOTriFunction; 068import org.apache.commons.io.input.BoundedInputStream; 069import org.apache.commons.io.input.CharSequenceReader; 070import org.apache.commons.io.input.QueueInputStream; 071import org.apache.commons.io.output.AppendableWriter; 072import org.apache.commons.io.output.ByteArrayOutputStream; 073import org.apache.commons.io.output.NullOutputStream; 074import org.apache.commons.io.output.NullWriter; 075import org.apache.commons.io.output.StringBuilderWriter; 076import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream; 077 078/** 079 * General IO stream manipulation utilities. 080 * <p> 081 * This class provides static utility methods for input/output operations. 082 * </p> 083 * <ul> 084 * <li>closeQuietly - these methods close a stream ignoring nulls and exceptions 085 * <li>toXxx/read - these methods read data from a stream 086 * <li>write - these methods write data to a stream 087 * <li>copy - these methods copy all the data from one stream to another 088 * <li>contentEquals - these methods compare the content of two streams 089 * </ul> 090 * <p> 091 * The byte-to-char methods and char-to-byte methods involve a conversion step. 092 * Two methods are provided in each case, one that uses the platform default 093 * encoding and the other which allows you to specify an encoding. You are 094 * encouraged to always specify an encoding because relying on the platform 095 * default can lead to unexpected results, for example when moving from 096 * development to production. 097 * </p> 098 * <p> 099 * All the methods in this class that read a stream are buffered internally. 100 * This means that there is no cause to use a {@link BufferedInputStream} 101 * or {@link BufferedReader}. The default buffer size of 4K has been shown 102 * to be efficient in tests. 103 * </p> 104 * <p> 105 * The various copy methods all delegate the actual copying to one of the following methods: 106 * </p> 107 * <ul> 108 * <li>{@link #copyLarge(InputStream, OutputStream, byte[])}</li> 109 * <li>{@link #copyLarge(InputStream, OutputStream, long, long, byte[])}</li> 110 * <li>{@link #copyLarge(Reader, Writer, char[])}</li> 111 * <li>{@link #copyLarge(Reader, Writer, long, long, char[])}</li> 112 * </ul> 113 * For example, {@link #copy(InputStream, OutputStream)} calls {@link #copyLarge(InputStream, OutputStream)} 114 * which calls {@link #copy(InputStream, OutputStream, int)} which creates the buffer and calls 115 * {@link #copyLarge(InputStream, OutputStream, byte[])}. 116 * <p> 117 * Applications can re-use buffers by using the underlying methods directly. 118 * This may improve performance for applications that need to do a lot of copying. 119 * </p> 120 * <p> 121 * Wherever possible, the methods in this class do <em>not</em> flush or close 122 * the stream. This is to avoid making non-portable assumptions about the 123 * streams' origin and further use. Thus the caller is still responsible for 124 * closing streams after use. 125 * </p> 126 * <p> 127 * Provenance: Excalibur. 128 * </p> 129 */ 130public class IOUtils { 131 // NOTE: This class is focused on InputStream, OutputStream, Reader and 132 // Writer. Each method should take at least one of these as a parameter, 133 // or return one of them. 134 135 /** 136 * Holder for per-thread internal scratch buffer. 137 * 138 * <p>Buffers are created lazily and reused within the same thread to reduce allocation overhead. In the rare case of reentrant access, a temporary buffer 139 * is allocated to avoid data corruption.</p> 140 * 141 * <p>Typical usage:</p> 142 * 143 * <pre>{@code 144 * try (ScratchBytes scratch = ScratchBytes.get()) { 145 * // use the buffer 146 * byte[] bytes = scratch.array(); 147 * // ... 148 * } 149 * }</pre> 150 */ 151 static final class ScratchBytes implements AutoCloseable { 152 153 /** 154 * Wraps an internal byte array. 155 * 156 * [0] boolean in use. 157 * [1] byte[] buffer. 158 */ 159 private static final ThreadLocal<Object[]> LOCAL = ThreadLocal.withInitial(() -> new Object[] { false, byteArray() }); 160 161 private static final ScratchBytes INSTANCE = new ScratchBytes(null); 162 163 /** 164 * Gets the internal byte array buffer. 165 * 166 * @return the internal byte array buffer. 167 */ 168 static ScratchBytes get() { 169 final Object[] holder = LOCAL.get(); 170 // If already in use, return a new array 171 if ((boolean) holder[0]) { 172 return new ScratchBytes(byteArray()); 173 } 174 holder[0] = true; 175 return INSTANCE; 176 } 177 178 /** 179 * The buffer, or null if using the thread-local buffer. 180 */ 181 private final byte[] buffer; 182 183 private ScratchBytes(final byte[] buffer) { 184 this.buffer = buffer; 185 } 186 187 byte[] array() { 188 return buffer != null ? buffer : (byte[]) LOCAL.get()[1]; 189 } 190 191 /** 192 * If the buffer is the internal array, clear and release it for reuse. 193 */ 194 @Override 195 public void close() { 196 if (buffer == null) { 197 final Object[] holder = LOCAL.get(); 198 Arrays.fill((byte[]) holder[1], (byte) 0); 199 holder[0] = false; 200 } 201 } 202 } 203 204 /** 205 * Holder for per-thread internal scratch buffer. 206 * 207 * <p>Buffers are created lazily and reused within the same thread to reduce allocation overhead. In the rare case of reentrant access, a temporary buffer 208 * is allocated to avoid data corruption.</p> 209 * 210 * <p>Typical usage:</p> 211 * 212 * <pre>{@code 213 * try (ScratchChars scratch = ScratchChars.get()) { 214 * // use the buffer 215 * char[] bytes = scratch.array(); 216 * // ... 217 * } 218 * }</pre> 219 */ 220 static final class ScratchChars implements AutoCloseable { 221 222 /** 223 * Wraps an internal char array. 224 * 225 * [0] boolean in use. 226 * [1] char[] buffer. 227 */ 228 private static final ThreadLocal<Object[]> LOCAL = ThreadLocal.withInitial(() -> new Object[] { false, charArray() }); 229 230 private static final ScratchChars INSTANCE = new ScratchChars(null); 231 232 /** 233 * Gets the internal char array buffer. 234 * 235 * @return the internal char array buffer. 236 */ 237 static ScratchChars get() { 238 final Object[] holder = LOCAL.get(); 239 // If already in use, return a new array 240 if ((boolean) holder[0]) { 241 return new ScratchChars(charArray()); 242 } 243 holder[0] = true; 244 return INSTANCE; 245 } 246 247 /** 248 * The buffer, or null if using the thread-local buffer. 249 */ 250 private final char[] buffer; 251 252 private ScratchChars(final char[] buffer) { 253 this.buffer = buffer; 254 } 255 256 char[] array() { 257 return buffer != null ? buffer : (char[]) LOCAL.get()[1]; 258 } 259 260 /** 261 * If the buffer is the internal array, clear and release it for reuse. 262 */ 263 @Override 264 public void close() { 265 if (buffer == null) { 266 final Object[] holder = LOCAL.get(); 267 Arrays.fill((char[]) holder[1], (char) 0); 268 holder[0] = false; 269 } 270 } 271 } 272 273 /** 274 * CR char '{@value}'. 275 * 276 * @since 2.9.0 277 */ 278 public static final int CR = '\r'; 279 280 /** 281 * The default buffer size ({@value}) to use in copy methods. 282 */ 283 public static final int DEFAULT_BUFFER_SIZE = 8192; 284 285 /** 286 * The system directory separator character. 287 */ 288 public static final char DIR_SEPARATOR = File.separatorChar; 289 290 /** 291 * The Unix directory separator character '{@value}'. 292 */ 293 public static final char DIR_SEPARATOR_UNIX = '/'; 294 295 /** 296 * The Windows directory separator character '{@value}'. 297 */ 298 public static final char DIR_SEPARATOR_WINDOWS = '\\'; 299 300 /** 301 * A singleton empty byte array. 302 * 303 * @since 2.9.0 304 */ 305 public static final byte[] EMPTY_BYTE_ARRAY = {}; 306 307 /** 308 * Represents the end-of-file (or stream) value {@value}. 309 * @since 2.5 (made public) 310 */ 311 public static final int EOF = -1; 312 313 /** 314 * LF char '{@value}'. 315 * 316 * @since 2.9.0 317 */ 318 public static final int LF = '\n'; 319 320 /** 321 * The system line separator string. 322 * 323 * @deprecated Use {@link System#lineSeparator()}. 324 */ 325 @Deprecated 326 public static final String LINE_SEPARATOR = System.lineSeparator(); 327 328 /** 329 * The Unix line separator string. 330 * 331 * @see StandardLineSeparator#LF 332 */ 333 public static final String LINE_SEPARATOR_UNIX = StandardLineSeparator.LF.getString(); 334 335 /** 336 * The Windows line separator string. 337 * 338 * @see StandardLineSeparator#CRLF 339 */ 340 public static final String LINE_SEPARATOR_WINDOWS = StandardLineSeparator.CRLF.getString(); 341 342 /** 343 * The maximum size of an array in many Java VMs. 344 * <p> 345 * The constant is copied from OpenJDK's {@code jdk.internal.util.ArraysSupport#SOFT_MAX_ARRAY_LENGTH}. 346 * </p> 347 * 348 * @since 2.21.0 349 */ 350 public static final int SOFT_MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8; 351 352 /** 353 * Returns the given InputStream if it is already a {@link BufferedInputStream}, otherwise creates a 354 * BufferedInputStream from the given InputStream. 355 * 356 * @param inputStream the InputStream to wrap or return (not null). 357 * @return the given InputStream or a new {@link BufferedInputStream} for the given InputStream. 358 * @throws NullPointerException if the input parameter is null. 359 * @since 2.5 360 */ 361 @SuppressWarnings("resource") // parameter null check 362 public static BufferedInputStream buffer(final InputStream inputStream) { 363 // reject null early on rather than waiting for IO operation to fail 364 // not checked by BufferedInputStream 365 Objects.requireNonNull(inputStream, "inputStream"); 366 return inputStream instanceof BufferedInputStream ? 367 (BufferedInputStream) inputStream : new BufferedInputStream(inputStream); 368 } 369 370 /** 371 * Returns the given InputStream if it is already a {@link BufferedInputStream}, otherwise creates a 372 * BufferedInputStream from the given InputStream. 373 * 374 * @param inputStream the InputStream to wrap or return (not null). 375 * @param size the buffer size, if a new BufferedInputStream is created. 376 * @return the given InputStream or a new {@link BufferedInputStream} for the given InputStream. 377 * @throws NullPointerException if the input parameter is null. 378 * @since 2.5 379 */ 380 @SuppressWarnings("resource") // parameter null check 381 public static BufferedInputStream buffer(final InputStream inputStream, final int size) { 382 // reject null early on rather than waiting for IO operation to fail 383 // not checked by BufferedInputStream 384 Objects.requireNonNull(inputStream, "inputStream"); 385 return inputStream instanceof BufferedInputStream ? 386 (BufferedInputStream) inputStream : new BufferedInputStream(inputStream, size); 387 } 388 389 /** 390 * Returns the given OutputStream if it is already a {@link BufferedOutputStream}, otherwise creates a 391 * BufferedOutputStream from the given OutputStream. 392 * 393 * @param outputStream the OutputStream to wrap or return (not null). 394 * @return the given OutputStream or a new {@link BufferedOutputStream} for the given OutputStream 395 * @throws NullPointerException if the input parameter is null. 396 * @since 2.5 397 */ 398 @SuppressWarnings("resource") // parameter null check 399 public static BufferedOutputStream buffer(final OutputStream outputStream) { 400 // reject null early on rather than waiting for IO operation to fail 401 // not checked by BufferedInputStream 402 Objects.requireNonNull(outputStream, "outputStream"); 403 return outputStream instanceof BufferedOutputStream ? 404 (BufferedOutputStream) outputStream : new BufferedOutputStream(outputStream); 405 } 406 407 /** 408 * Returns the given OutputStream if it is already a {@link BufferedOutputStream}, otherwise creates a 409 * BufferedOutputStream from the given OutputStream. 410 * 411 * @param outputStream the OutputStream to wrap or return (not null). 412 * @param size the buffer size, if a new BufferedOutputStream is created. 413 * @return the given OutputStream or a new {@link BufferedOutputStream} for the given OutputStream. 414 * @throws NullPointerException if the input parameter is null. 415 * @since 2.5 416 */ 417 @SuppressWarnings("resource") // parameter null check 418 public static BufferedOutputStream buffer(final OutputStream outputStream, final int size) { 419 // reject null early on rather than waiting for IO operation to fail 420 // not checked by BufferedInputStream 421 Objects.requireNonNull(outputStream, "outputStream"); 422 return outputStream instanceof BufferedOutputStream ? 423 (BufferedOutputStream) outputStream : new BufferedOutputStream(outputStream, size); 424 } 425 426 /** 427 * Returns the given reader if it is already a {@link BufferedReader}, otherwise creates a BufferedReader from 428 * the given reader. 429 * 430 * @param reader the reader to wrap or return (not null). 431 * @return the given reader or a new {@link BufferedReader} for the given reader. 432 * @throws NullPointerException if the input parameter is null. 433 * @since 2.5 434 */ 435 public static BufferedReader buffer(final Reader reader) { 436 return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader); 437 } 438 439 /** 440 * Returns the given reader if it is already a {@link BufferedReader}, otherwise creates a BufferedReader from the 441 * given reader. 442 * 443 * @param reader the reader to wrap or return (not null). 444 * @param size the buffer size, if a new BufferedReader is created. 445 * @return the given reader or a new {@link BufferedReader} for the given reader. 446 * @throws NullPointerException if the input parameter is null. 447 * @since 2.5 448 */ 449 public static BufferedReader buffer(final Reader reader, final int size) { 450 return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader, size); 451 } 452 453 /** 454 * Returns the given Writer if it is already a {@link BufferedWriter}, otherwise creates a BufferedWriter from the 455 * given Writer. 456 * 457 * @param writer the Writer to wrap or return (not null). 458 * @return the given Writer or a new {@link BufferedWriter} for the given Writer. 459 * @throws NullPointerException if the input parameter is null. 460 * @since 2.5 461 */ 462 public static BufferedWriter buffer(final Writer writer) { 463 return writer instanceof BufferedWriter ? (BufferedWriter) writer : new BufferedWriter(writer); 464 } 465 466 /** 467 * Returns the given Writer if it is already a {@link BufferedWriter}, otherwise creates a BufferedWriter from the 468 * given Writer. 469 * 470 * @param writer the Writer to wrap or return (not null). 471 * @param size the buffer size, if a new BufferedWriter is created. 472 * @return the given Writer or a new {@link BufferedWriter} for the given Writer. 473 * @throws NullPointerException if the input parameter is null. 474 * @since 2.5 475 */ 476 public static BufferedWriter buffer(final Writer writer, final int size) { 477 return writer instanceof BufferedWriter ? (BufferedWriter) writer : new BufferedWriter(writer, size); 478 } 479 480 /** 481 * Returns a new byte array of size {@link #DEFAULT_BUFFER_SIZE}. 482 * 483 * @return a new byte array of size {@link #DEFAULT_BUFFER_SIZE}. 484 * @since 2.9.0 485 */ 486 public static byte[] byteArray() { 487 return byteArray(DEFAULT_BUFFER_SIZE); 488 } 489 490 /** 491 * Returns a new byte array of the given size. 492 * 493 * TODO Consider guarding or warning against large allocations. 494 * 495 * @param size array size. 496 * @return a new byte array of the given size. 497 * @throws NegativeArraySizeException if the size is negative. 498 * @since 2.9.0 499 */ 500 public static byte[] byteArray(final int size) { 501 return new byte[size]; 502 } 503 504 /** 505 * Returns a new char array of size {@link #DEFAULT_BUFFER_SIZE}. 506 * 507 * @return a new char array of size {@link #DEFAULT_BUFFER_SIZE}. 508 * @since 2.9.0 509 */ 510 private static char[] charArray() { 511 return charArray(DEFAULT_BUFFER_SIZE); 512 } 513 514 /** 515 * Returns a new char array of the given size. 516 * 517 * TODO Consider guarding or warning against large allocations. 518 * 519 * @param size array size. 520 * @return a new char array of the given size. 521 * @since 2.9.0 522 */ 523 private static char[] charArray(final int size) { 524 return new char[size]; 525 } 526 527 /** 528 * Validates that the sub-range {@code [off, off + len)} is within the bounds of the given array. 529 * 530 * <p>The range is valid if all of the following hold:</p> 531 * <ul> 532 * <li>{@code off >= 0}</li> 533 * <li>{@code len >= 0}</li> 534 * <li>{@code off + len <= array.length}</li> 535 * </ul> 536 * 537 * <p>If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.</p> 538 * 539 * <p>Typical usage in {@link InputStream#read(byte[], int, int)} and {@link OutputStream#write(byte[], int, int)} implementations:</p> 540 * 541 * <pre><code> 542 * public int read(byte[] b, int off, int len) throws IOException { 543 * IOUtils.checkFromIndexSize(b, off, len); 544 * if (len == 0) { 545 * return 0; 546 * } 547 * ensureOpen(); 548 * // perform read... 549 * } 550 * 551 * public void write(byte[] b, int off, int len) throws IOException { 552 * IOUtils.checkFromIndexSize(b, off, len); 553 * if (len == 0) { 554 * return; 555 * } 556 * ensureOpen(); 557 * // perform write... 558 * } 559 * </code></pre> 560 * 561 * @param array the array against which the range is validated 562 * @param off the starting offset into the array (inclusive) 563 * @param len the number of elements to access 564 * @throws NullPointerException if {@code array} is {@code null} 565 * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code array} 566 * @see InputStream#read(byte[], int, int) 567 * @see OutputStream#write(byte[], int, int) 568 * @since 2.21.0 569 */ 570 public static void checkFromIndexSize(final byte[] array, final int off, final int len) { 571 checkFromIndexSize(off, len, Objects.requireNonNull(array, "byte array").length); 572 } 573 574 /** 575 * Validates that the sub-range {@code [off, off + len)} is within the bounds of the given array. 576 * 577 * <p>The range is valid if all of the following hold:</p> 578 * <ul> 579 * <li>{@code off >= 0}</li> 580 * <li>{@code len >= 0}</li> 581 * <li>{@code off + len <= array.length}</li> 582 * </ul> 583 * 584 * <p>If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.</p> 585 * 586 * <p>Typical usage in {@link Reader#read(char[], int, int)} and {@link Writer#write(char[], int, int)} implementations:</p> 587 * 588 * <pre><code> 589 * public int read(char[] cbuf, int off, int len) throws IOException { 590 * ensureOpen(); 591 * IOUtils.checkFromIndexSize(cbuf, off, len); 592 * if (len == 0) { 593 * return 0; 594 * } 595 * // perform read... 596 * } 597 * 598 * public void write(char[] cbuf, int off, int len) throws IOException { 599 * ensureOpen(); 600 * IOUtils.checkFromIndexSize(cbuf, off, len); 601 * if (len == 0) { 602 * return; 603 * } 604 * // perform write... 605 * } 606 * </code></pre> 607 * 608 * @param array the array against which the range is validated 609 * @param off the starting offset into the array (inclusive) 610 * @param len the number of characters to access 611 * @throws NullPointerException if {@code array} is {@code null} 612 * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code array} 613 * @see Reader#read(char[], int, int) 614 * @see Writer#write(char[], int, int) 615 * @since 2.21.0 616 */ 617 public static void checkFromIndexSize(final char[] array, final int off, final int len) { 618 checkFromIndexSize(off, len, Objects.requireNonNull(array, "char array").length); 619 } 620 621 static void checkFromIndexSize(final int off, final int len, final int arrayLength) { 622 if ((off | len | arrayLength) < 0 || arrayLength - len < off) { 623 throw new IndexOutOfBoundsException(String.format("Range [%s, %<s + %s) out of bounds for length %s", off, len, arrayLength)); 624 } 625 } 626 627 /** 628 * Validates that the sub-range {@code [off, off + len)} is within the bounds of the given string. 629 * 630 * <p>The range is valid if all of the following hold:</p> 631 * <ul> 632 * <li>{@code off >= 0}</li> 633 * <li>{@code len >= 0}</li> 634 * <li>{@code off + len <= str.length()}</li> 635 * </ul> 636 * 637 * <p>If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.</p> 638 * 639 * <p>Typical usage in {@link Writer#write(String, int, int)} implementations:</p> 640 * 641 * <pre><code> 642 * public void write(String str, int off, int len) throws IOException { 643 * IOUtils.checkFromIndexSize(str, off, len); 644 * if (len == 0) { 645 * return; 646 * } 647 * // perform write... 648 * } 649 * </code></pre> 650 * 651 * @param str the string against which the range is validated 652 * @param off the starting offset into the string (inclusive) 653 * @param len the number of characters to write 654 * @throws NullPointerException if {@code str} is {@code null} 655 * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code str} 656 * @see Writer#write(String, int, int) 657 * @since 2.21.0 658 */ 659 public static void checkFromIndexSize(final String str, final int off, final int len) { 660 checkFromIndexSize(off, len, Objects.requireNonNull(str, "str").length()); 661 } 662 663 /** 664 * Validates that the sub-sequence {@code [fromIndex, toIndex)} is within the bounds of the given {@link CharSequence}. 665 * 666 * <p>The sub-sequence is valid if all of the following hold:</p> 667 * <ul> 668 * <li>{@code fromIndex >= 0}</li> 669 * <li>{@code fromIndex <= toIndex}</li> 670 * <li>{@code toIndex <= seq.length()}</li> 671 * </ul> 672 * 673 * <p>If {@code seq} is {@code null}, it is treated as the literal string {@code "null"} (length {@code 4}).</p> 674 * 675 * <p>If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.</p> 676 * 677 * <p>Typical usage in {@link Appendable#append(CharSequence, int, int)} implementations:</p> 678 * 679 * <pre><code> 680 * public Appendable append(CharSequence csq, int start, int end) throws IOException { 681 * IOUtils.checkFromToIndex(csq, start, end); 682 * // perform append... 683 * return this; 684 * } 685 * </code></pre> 686 * 687 * @param seq the character sequence to validate (may be {@code null}, treated as {@code "null"}) 688 * @param fromIndex the starting index (inclusive) 689 * @param toIndex the ending index (exclusive) 690 * @throws IndexOutOfBoundsException if the range {@code [fromIndex, toIndex)} is out of bounds for {@code seq} 691 * @see Appendable#append(CharSequence, int, int) 692 * @since 2.21.0 693 */ 694 public static void checkFromToIndex(final CharSequence seq, final int fromIndex, final int toIndex) { 695 checkFromToIndex(fromIndex, toIndex, seq != null ? seq.length() : 4); 696 } 697 698 static void checkFromToIndex(final int fromIndex, final int toIndex, final int length) { 699 if (fromIndex < 0 || toIndex < fromIndex || length < toIndex) { 700 throw new IndexOutOfBoundsException(String.format("Range [%s, %s) out of bounds for length %s", fromIndex, toIndex, length)); 701 } 702 } 703 704 /** 705 * Clears any state. 706 * <ul> 707 * <li>Removes the current thread's value for thread-local variables.</li> 708 * <li>Sets static scratch arrays to 0s.</li> 709 * </ul> 710 * @see IO#clear() 711 */ 712 static void clear() { 713 ScratchBytes.LOCAL.remove(); 714 ScratchChars.LOCAL.remove(); 715 } 716 717 /** 718 * Closes the given {@link Closeable} as a null-safe operation. 719 * 720 * @param closeable The resource to close, may be null. 721 * @throws IOException if an I/O error occurs. 722 * @since 2.7 723 */ 724 public static void close(final Closeable closeable) throws IOException { 725 if (closeable != null) { 726 closeable.close(); 727 } 728 } 729 730 /** 731 * Closes the given {@link Closeable}s as null-safe operations. 732 * 733 * @param closeables The resource(s) to close, may be null. 734 * @throws IOExceptionList if an I/O error occurs. 735 * @since 2.8.0 736 */ 737 public static void close(final Closeable... closeables) throws IOExceptionList { 738 IOConsumer.forAll(IOUtils::close, closeables); 739 } 740 741 /** 742 * Closes the given {@link Closeable} as a null-safe operation. 743 * 744 * @param closeable The resource to close, may be null. 745 * @param consumer Consume the IOException thrown by {@link Closeable#close()}. 746 * @throws IOException if an I/O error occurs. 747 * @since 2.7 748 */ 749 public static void close(final Closeable closeable, final IOConsumer<IOException> consumer) throws IOException { 750 if (closeable != null) { 751 try { 752 closeable.close(); 753 } catch (final IOException e) { 754 if (consumer != null) { 755 consumer.accept(e); 756 } 757 } catch (final Exception e) { 758 if (consumer != null) { 759 consumer.accept(new IOException(e)); 760 } 761 } 762 } 763 } 764 765 /** 766 * Closes a URLConnection. 767 * 768 * @param conn the connection to close. 769 * @since 2.4 770 */ 771 public static void close(final URLConnection conn) { 772 if (conn instanceof HttpURLConnection) { 773 ((HttpURLConnection) conn).disconnect(); 774 } 775 } 776 777 /** 778 * Avoids the need to type cast. 779 * 780 * @param closeable the object to close, may be null. 781 */ 782 private static void closeQ(final Closeable closeable) { 783 closeQuietly(closeable, null); 784 } 785 786 /** 787 * Closes a {@link Closeable} unconditionally. 788 * 789 * <p> 790 * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored. This is typically used in 791 * finally blocks. 792 * <p> 793 * Example code: 794 * </p> 795 * <pre> 796 * Closeable closeable = null; 797 * try { 798 * closeable = new FileReader("foo.txt"); 799 * // process closeable 800 * closeable.close(); 801 * } catch (Exception e) { 802 * // error handling 803 * } finally { 804 * IOUtils.closeQuietly(closeable); 805 * } 806 * </pre> 807 * <p> 808 * Closing all streams: 809 * </p> 810 * <pre> 811 * try { 812 * return IOUtils.copy(inputStream, outputStream); 813 * } finally { 814 * IOUtils.closeQuietly(inputStream); 815 * IOUtils.closeQuietly(outputStream); 816 * } 817 * </pre> 818 * <p> 819 * Also consider using a try-with-resources statement where appropriate. 820 * </p> 821 * 822 * @param closeable the objects to close, may be null or already closed. 823 * @since 2.0 824 * @see Throwable#addSuppressed(Throwable) 825 */ 826 public static void closeQuietly(final Closeable closeable) { 827 closeQuietly(closeable, null); 828 } 829 830 /** 831 * Closes a {@link Closeable} unconditionally. 832 * <p> 833 * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored. 834 * <p> 835 * This is typically used in finally blocks to ensure that the closeable is closed 836 * even if an Exception was thrown before the normal close statement was reached. 837 * <br> 838 * <b>It should not be used to replace the close statement(s) 839 * which should be present for the non-exceptional case.</b> 840 * <br> 841 * It is only intended to simplify tidying up where normal processing has already failed 842 * and reporting close failure as well is not necessary or useful. 843 * <p> 844 * Example code: 845 * </p> 846 * <pre> 847 * Closeable closeable = null; 848 * try { 849 * closeable = new FileReader("foo.txt"); 850 * // processing using the closeable; may throw an Exception 851 * closeable.close(); // Normal close - exceptions not ignored 852 * } catch (Exception e) { 853 * // error handling 854 * } finally { 855 * <strong>IOUtils.closeQuietly(closeable); // In case normal close was skipped due to Exception</strong> 856 * } 857 * </pre> 858 * <p> 859 * Closing all streams: 860 * <br> 861 * <pre> 862 * try { 863 * return IOUtils.copy(inputStream, outputStream); 864 * } finally { 865 * IOUtils.closeQuietly(inputStream, outputStream); 866 * } 867 * </pre> 868 * <p> 869 * Also consider using a try-with-resources statement where appropriate. 870 * </p> 871 * @param closeables the objects to close, may be null or already closed. 872 * @see #closeQuietly(Closeable) 873 * @since 2.5 874 * @see Throwable#addSuppressed(Throwable) 875 */ 876 public static void closeQuietly(final Closeable... closeables) { 877 if (closeables != null) { 878 closeQuietly(Arrays.stream(closeables)); 879 } 880 } 881 882 /** 883 * Closes the given {@link Closeable} as a null-safe operation while consuming IOException by the given {@code consumer}. 884 * 885 * @param closeable The resource to close, may be null. 886 * @param consumer Consumes the Exception thrown by {@link Closeable#close()}. 887 * @since 2.7 888 */ 889 public static void closeQuietly(final Closeable closeable, final Consumer<Exception> consumer) { 890 if (closeable != null) { 891 try { 892 closeable.close(); 893 } catch (final Exception e) { 894 if (consumer != null) { 895 consumer.accept(e); 896 } 897 } 898 } 899 } 900 901 /** 902 * Closes an {@link InputStream} unconditionally. 903 * <p> 904 * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored. 905 * This is typically used in finally blocks. 906 * </p> 907 * <p> 908 * Example code: 909 * </p> 910 * <pre> 911 * byte[] data = new byte[1024]; 912 * InputStream in = null; 913 * try { 914 * in = new FileInputStream("foo.txt"); 915 * in.read(data); 916 * in.close(); //close errors are handled 917 * } catch (Exception e) { 918 * // error handling 919 * } finally { 920 * IOUtils.closeQuietly(in); 921 * } 922 * </pre> 923 * <p> 924 * Also consider using a try-with-resources statement where appropriate. 925 * </p> 926 * 927 * @param input the InputStream to close, may be null or already closed. 928 * @see Throwable#addSuppressed(Throwable) 929 */ 930 public static void closeQuietly(final InputStream input) { 931 closeQ(input); 932 } 933 934 /** 935 * Closes an iterable of {@link Closeable} unconditionally. 936 * <p> 937 * Equivalent calling {@link Closeable#close()} on each element, except any exceptions will be ignored. 938 * </p> 939 * 940 * @param closeables the objects to close, may be null or already closed. 941 * @see #closeQuietly(Closeable) 942 * @since 2.12.0 943 */ 944 public static void closeQuietly(final Iterable<Closeable> closeables) { 945 if (closeables != null) { 946 closeables.forEach(IOUtils::closeQuietly); 947 } 948 } 949 950 /** 951 * Closes an {@link OutputStream} unconditionally. 952 * <p> 953 * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored. 954 * This is typically used in finally blocks. 955 * </p> 956 * <p> 957 * Example code: 958 * </p> 959 * <pre> 960 * byte[] data = "Hello, World".getBytes(); 961 * 962 * OutputStream out = null; 963 * try { 964 * out = new FileOutputStream("foo.txt"); 965 * out.write(data); 966 * out.close(); //close errors are handled 967 * } catch (IOException e) { 968 * // error handling 969 * } finally { 970 * IOUtils.closeQuietly(out); 971 * } 972 * </pre> 973 * <p> 974 * Also consider using a try-with-resources statement where appropriate. 975 * </p> 976 * 977 * @param output the OutputStream to close, may be null or already closed. 978 * @see Throwable#addSuppressed(Throwable) 979 */ 980 public static void closeQuietly(final OutputStream output) { 981 closeQ(output); 982 } 983 984 /** 985 * Closes an {@link Reader} unconditionally. 986 * <p> 987 * Equivalent to {@link Reader#close()}, except any exceptions will be ignored. 988 * This is typically used in finally blocks. 989 * </p> 990 * <p> 991 * Example code: 992 * </p> 993 * <pre> 994 * char[] data = new char[1024]; 995 * Reader in = null; 996 * try { 997 * in = new FileReader("foo.txt"); 998 * in.read(data); 999 * in.close(); //close errors are handled 1000 * } catch (Exception e) { 1001 * // error handling 1002 * } finally { 1003 * IOUtils.closeQuietly(in); 1004 * } 1005 * </pre> 1006 * <p> 1007 * Also consider using a try-with-resources statement where appropriate. 1008 * </p> 1009 * 1010 * @param reader the Reader to close, may be null or already closed. 1011 * @see Throwable#addSuppressed(Throwable) 1012 */ 1013 public static void closeQuietly(final Reader reader) { 1014 closeQ(reader); 1015 } 1016 1017 /** 1018 * Closes a {@link Selector} unconditionally. 1019 * <p> 1020 * Equivalent to {@link Selector#close()}, except any exceptions will be ignored. 1021 * This is typically used in finally blocks. 1022 * </p> 1023 * <p> 1024 * Example code: 1025 * </p> 1026 * <pre> 1027 * Selector selector = null; 1028 * try { 1029 * selector = Selector.open(); 1030 * // process socket 1031 * 1032 * } catch (Exception e) { 1033 * // error handling 1034 * } finally { 1035 * IOUtils.closeQuietly(selector); 1036 * } 1037 * </pre> 1038 * <p> 1039 * Also consider using a try-with-resources statement where appropriate. 1040 * </p> 1041 * 1042 * @param selector the Selector to close, may be null or already closed. 1043 * @since 2.2 1044 * @see Throwable#addSuppressed(Throwable) 1045 */ 1046 public static void closeQuietly(final Selector selector) { 1047 closeQ(selector); 1048 } 1049 1050 /** 1051 * Closes a {@link ServerSocket} unconditionally. 1052 * <p> 1053 * Equivalent to {@link ServerSocket#close()}, except any exceptions will be ignored. 1054 * This is typically used in finally blocks. 1055 * </p> 1056 * <p> 1057 * Example code: 1058 * </p> 1059 * <pre> 1060 * ServerSocket socket = null; 1061 * try { 1062 * socket = new ServerSocket(); 1063 * // process socket 1064 * socket.close(); 1065 * } catch (Exception e) { 1066 * // error handling 1067 * } finally { 1068 * IOUtils.closeQuietly(socket); 1069 * } 1070 * </pre> 1071 * <p> 1072 * Also consider using a try-with-resources statement where appropriate. 1073 * </p> 1074 * 1075 * @param serverSocket the ServerSocket to close, may be null or already closed. 1076 * @since 2.2 1077 * @see Throwable#addSuppressed(Throwable) 1078 */ 1079 public static void closeQuietly(final ServerSocket serverSocket) { 1080 closeQ(serverSocket); 1081 } 1082 1083 /** 1084 * Closes a {@link Socket} unconditionally. 1085 * <p> 1086 * Equivalent to {@link Socket#close()}, except any exceptions will be ignored. 1087 * This is typically used in finally blocks. 1088 * </p> 1089 * <p> 1090 * Example code: 1091 * </p> 1092 * <pre> 1093 * Socket socket = null; 1094 * try { 1095 * socket = new Socket("http://www.foo.com/", 80); 1096 * // process socket 1097 * socket.close(); 1098 * } catch (Exception e) { 1099 * // error handling 1100 * } finally { 1101 * IOUtils.closeQuietly(socket); 1102 * } 1103 * </pre> 1104 * <p> 1105 * Also consider using a try-with-resources statement where appropriate. 1106 * </p> 1107 * 1108 * @param socket the Socket to close, may be null or already closed. 1109 * @since 2.0 1110 * @see Throwable#addSuppressed(Throwable) 1111 */ 1112 public static void closeQuietly(final Socket socket) { 1113 closeQ(socket); 1114 } 1115 1116 /** 1117 * Closes a stream of {@link Closeable} unconditionally. 1118 * <p> 1119 * Equivalent calling {@link Closeable#close()} on each element, except any exceptions will be ignored. 1120 * </p> 1121 * 1122 * @param closeables the objects to close, may be null or already closed. 1123 * @see #closeQuietly(Closeable) 1124 * @since 2.12.0 1125 */ 1126 public static void closeQuietly(final Stream<Closeable> closeables) { 1127 if (closeables != null) { 1128 closeables.forEach(IOUtils::closeQuietly); 1129 } 1130 } 1131 1132 /** 1133 * Closes an {@link Writer} unconditionally. 1134 * <p> 1135 * Equivalent to {@link Writer#close()}, except any exceptions will be ignored. 1136 * This is typically used in finally blocks. 1137 * </p> 1138 * <p> 1139 * Example code: 1140 * </p> 1141 * <pre> 1142 * Writer out = null; 1143 * try { 1144 * out = new StringWriter(); 1145 * out.write("Hello World"); 1146 * out.close(); //close errors are handled 1147 * } catch (Exception e) { 1148 * // error handling 1149 * } finally { 1150 * IOUtils.closeQuietly(out); 1151 * } 1152 * </pre> 1153 * <p> 1154 * Also consider using a try-with-resources statement where appropriate. 1155 * </p> 1156 * 1157 * @param writer the Writer to close, may be null or already closed. 1158 * @see Throwable#addSuppressed(Throwable) 1159 */ 1160 public static void closeQuietly(final Writer writer) { 1161 closeQ(writer); 1162 } 1163 1164 /** 1165 * Consumes bytes from a {@link InputStream} and ignores them. 1166 * <p> 1167 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. 1168 * </p> 1169 * 1170 * @param input the {@link InputStream} to read. 1171 * @return the number of bytes copied. or {@code 0} if {@code input is null}. 1172 * @throws NullPointerException if the InputStream is {@code null}. 1173 * @throws IOException if an I/O error occurs. 1174 * @since 2.8.0 1175 */ 1176 public static long consume(final InputStream input) throws IOException { 1177 return copyLarge(input, NullOutputStream.INSTANCE); 1178 } 1179 1180 /** 1181 * Consumes characters from a {@link Reader} and ignores them. 1182 * <p> 1183 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. 1184 * </p> 1185 * 1186 * @param input the {@link Reader} to read. 1187 * @return the number of bytes copied. or {@code 0} if {@code input is null}. 1188 * @throws NullPointerException if the Reader is {@code null}. 1189 * @throws IOException if an I/O error occurs. 1190 * @since 2.12.0 1191 */ 1192 public static long consume(final Reader input) throws IOException { 1193 return copyLarge(input, NullWriter.INSTANCE); 1194 } 1195 1196 /** 1197 * Compares the contents of two Streams to determine if they are equal or 1198 * not. 1199 * <p> 1200 * This method buffers the input internally using 1201 * {@link BufferedInputStream} if they are not already buffered. 1202 * </p> 1203 * 1204 * @param input1 the first stream. 1205 * @param input2 the second stream. 1206 * @return true if the content of the streams are equal or they both don't. 1207 * exist, false otherwise. 1208 * @throws IOException if an I/O error occurs. 1209 */ 1210 @SuppressWarnings("resource") // Caller closes input streams 1211 public static boolean contentEquals(final InputStream input1, final InputStream input2) throws IOException { 1212 // Before making any changes, please test with org.apache.commons.io.jmh.IOUtilsContentEqualsInputStreamsBenchmark 1213 if (input1 == input2) { 1214 return true; 1215 } 1216 if (input1 == null || input2 == null) { 1217 return false; 1218 } 1219 // We do not close FileChannels because that closes the owning InputStream. 1220 return FileChannels.contentEquals(Channels.newChannel(input1), Channels.newChannel(input2), DEFAULT_BUFFER_SIZE); 1221 } 1222 1223 // TODO Consider making public 1224 private static boolean contentEquals(final Iterator<?> iterator1, final Iterator<?> iterator2) { 1225 while (iterator1.hasNext()) { 1226 if (!iterator2.hasNext()) { 1227 return false; 1228 } 1229 if (!Objects.equals(iterator1.next(), iterator2.next())) { 1230 return false; 1231 } 1232 } 1233 return !iterator2.hasNext(); 1234 } 1235 1236 /** 1237 * Compares the contents of two Readers to determine if they are equal or not. 1238 * <p> 1239 * This method buffers the input internally using {@link BufferedReader} if they are not already buffered. 1240 * </p> 1241 * 1242 * @param input1 the first reader. 1243 * @param input2 the second reader. 1244 * @return true if the content of the readers are equal or they both don't exist, false otherwise. 1245 * @throws NullPointerException if either input is null. 1246 * @throws IOException if an I/O error occurs. 1247 * @since 1.1 1248 */ 1249 public static boolean contentEquals(final Reader input1, final Reader input2) throws IOException { 1250 if (input1 == input2) { 1251 return true; 1252 } 1253 if (input1 == null || input2 == null) { 1254 return false; 1255 } 1256 1257 // reuse one 1258 try (ScratchChars scratch = IOUtils.ScratchChars.get()) { 1259 final char[] array1 = scratch.array(); 1260 // but allocate another 1261 final char[] array2 = charArray(); 1262 int pos1; 1263 int pos2; 1264 int count1; 1265 int count2; 1266 while (true) { 1267 pos1 = 0; 1268 pos2 = 0; 1269 for (int index = 0; index < DEFAULT_BUFFER_SIZE; index++) { 1270 if (pos1 == index) { 1271 do { 1272 count1 = input1.read(array1, pos1, DEFAULT_BUFFER_SIZE - pos1); 1273 } while (count1 == 0); 1274 if (count1 == EOF) { 1275 return pos2 == index && input2.read() == EOF; 1276 } 1277 pos1 += count1; 1278 } 1279 if (pos2 == index) { 1280 do { 1281 count2 = input2.read(array2, pos2, DEFAULT_BUFFER_SIZE - pos2); 1282 } while (count2 == 0); 1283 if (count2 == EOF) { 1284 return pos1 == index && input1.read() == EOF; 1285 } 1286 pos2 += count2; 1287 } 1288 if (array1[index] != array2[index]) { 1289 return false; 1290 } 1291 } 1292 } 1293 } 1294 } 1295 1296 // TODO Consider making public 1297 private static boolean contentEquals(final Stream<?> stream1, final Stream<?> stream2) { 1298 if (stream1 == stream2) { 1299 return true; 1300 } 1301 if (stream1 == null || stream2 == null) { 1302 return false; 1303 } 1304 return contentEquals(stream1.iterator(), stream2.iterator()); 1305 } 1306 1307 // TODO Consider making public 1308 private static boolean contentEqualsIgnoreEOL(final BufferedReader reader1, final BufferedReader reader2) { 1309 if (reader1 == reader2) { 1310 return true; 1311 } 1312 if (reader1 == null || reader2 == null) { 1313 return false; 1314 } 1315 return contentEquals(reader1.lines(), reader2.lines()); 1316 } 1317 1318 /** 1319 * Compares the contents of two Readers to determine if they are equal or 1320 * not, ignoring EOL characters. 1321 * <p> 1322 * This method buffers the input internally using 1323 * {@link BufferedReader} if they are not already buffered. 1324 * </p> 1325 * 1326 * @param reader1 the first reader. 1327 * @param reader2 the second reader. 1328 * @return true if the content of the readers are equal (ignoring EOL differences), false otherwise. 1329 * @throws NullPointerException if either input is null. 1330 * @throws UncheckedIOException if an I/O error occurs. 1331 * @since 2.2 1332 */ 1333 @SuppressWarnings("resource") 1334 public static boolean contentEqualsIgnoreEOL(final Reader reader1, final Reader reader2) throws UncheckedIOException { 1335 if (reader1 == reader2) { 1336 return true; 1337 } 1338 if (reader1 == null || reader2 == null) { 1339 return false; 1340 } 1341 return contentEqualsIgnoreEOL(toBufferedReader(reader1), toBufferedReader(reader2)); 1342 } 1343 1344 /** 1345 * Copies bytes from an {@link InputStream} to an {@link OutputStream}. 1346 * <p> 1347 * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. 1348 * </p> 1349 * <p> 1350 * Large streams (over 2GB) will return a bytes copied value of {@code -1} after the copy has completed since 1351 * the correct number of bytes cannot be returned as an int. For large streams use the 1352 * {@link #copyLarge(InputStream, OutputStream)} method. 1353 * </p> 1354 * 1355 * @param inputStream the {@link InputStream} to read. 1356 * @param outputStream the {@link OutputStream} to write. 1357 * @return the number of bytes copied, or -1 if greater than {@link Integer#MAX_VALUE}. 1358 * @throws NullPointerException if the InputStream is {@code null}. 1359 * @throws NullPointerException if the OutputStream is {@code null}. 1360 * @throws IOException if an I/O error occurs. 1361 * @since 1.1 1362 */ 1363 public static int copy(final InputStream inputStream, final OutputStream outputStream) throws IOException { 1364 final long count = copyLarge(inputStream, outputStream); 1365 return count > Integer.MAX_VALUE ? EOF : (int) count; 1366 } 1367 1368 /** 1369 * Copies bytes from an {@link InputStream} to an {@link OutputStream} using an internal buffer of the 1370 * given size. 1371 * <p> 1372 * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. 1373 * </p> 1374 * 1375 * @param inputStream the {@link InputStream} to read. 1376 * @param outputStream the {@link OutputStream} to write to. 1377 * @param bufferSize the bufferSize used to copy from the input to the output. 1378 * @return the number of bytes copied. 1379 * @throws NullPointerException if the InputStream is {@code null}. 1380 * @throws NullPointerException if the OutputStream is {@code null}. 1381 * @throws IOException if an I/O error occurs. 1382 * @since 2.5 1383 */ 1384 public static long copy(final InputStream inputStream, final OutputStream outputStream, final int bufferSize) throws IOException { 1385 return copyLarge(inputStream, outputStream, byteArray(bufferSize)); 1386 } 1387 1388 /** 1389 * Copies bytes from an {@link InputStream} to chars on a 1390 * {@link Writer} using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. 1391 * <p> 1392 * This method buffers the input internally, so there is no need to use a 1393 * {@link BufferedInputStream}. 1394 * </p> 1395 * <p> 1396 * This method uses {@link InputStreamReader}. 1397 * </p> 1398 * 1399 * @param input the {@link InputStream} to read. 1400 * @param writer the {@link Writer} to write to. 1401 * @throws NullPointerException if the input or output is null. 1402 * @throws IOException if an I/O error occurs. 1403 * @since 1.1 1404 * @deprecated Use {@link #copy(InputStream, Writer, Charset)} instead. 1405 */ 1406 @Deprecated 1407 public static void copy(final InputStream input, final Writer writer) throws IOException { 1408 copy(input, writer, Charset.defaultCharset()); 1409 } 1410 1411 /** 1412 * Copies bytes from an {@link InputStream} to chars on a 1413 * {@link Writer} using the specified character encoding. 1414 * <p> 1415 * This method buffers the input internally, so there is no need to use a 1416 * {@link BufferedInputStream}. 1417 * </p> 1418 * <p> 1419 * This method uses {@link InputStreamReader}. 1420 * </p> 1421 * 1422 * @param input the {@link InputStream} to read. 1423 * @param writer the {@link Writer} to write to. 1424 * @param inputCharset the charset to use for the input stream, null means platform default. 1425 * @throws NullPointerException if the input or output is null. 1426 * @throws IOException if an I/O error occurs. 1427 * @since 2.3 1428 */ 1429 public static void copy(final InputStream input, final Writer writer, final Charset inputCharset) throws IOException { 1430 copy(new InputStreamReader(input, Charsets.toCharset(inputCharset)), writer); 1431 } 1432 1433 /** 1434 * Copies bytes from an {@link InputStream} to chars on a 1435 * {@link Writer} using the specified character encoding. 1436 * <p> 1437 * This method buffers the input internally, so there is no need to use a 1438 * {@link BufferedInputStream}. 1439 * </p> 1440 * <p> 1441 * Character encoding names can be found at 1442 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 1443 * </p> 1444 * <p> 1445 * This method uses {@link InputStreamReader}. 1446 * </p> 1447 * 1448 * @param input the {@link InputStream} to read 1449 * @param writer the {@link Writer} to write to 1450 * @param inputCharsetName the name of the requested charset for the InputStream, null means platform default. 1451 * @throws NullPointerException if the input or output is null. 1452 * @throws IOException if an I/O error occurs. 1453 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 1454 * @since 1.1 1455 */ 1456 public static void copy(final InputStream input, final Writer writer, final String inputCharsetName) throws IOException { 1457 copy(input, writer, Charsets.toCharset(inputCharsetName)); 1458 } 1459 1460 /** 1461 * Copies bytes from a {@link ByteArrayOutputStream} to a {@link QueueInputStream}. 1462 * <p> 1463 * Unlike using JDK {@link PipedInputStream} and {@link PipedOutputStream} for this, this 1464 * solution works safely in a single thread environment. 1465 * </p> 1466 * <p> 1467 * Example usage: 1468 * </p> 1469 * 1470 * <pre> 1471 * ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 1472 * outputStream.writeBytes("hello world".getBytes(StandardCharsets.UTF_8)); 1473 * 1474 * InputStream inputStream = IOUtils.copy(outputStream); 1475 * </pre> 1476 * 1477 * @param outputStream the {@link ByteArrayOutputStream} to read. 1478 * @return the {@link QueueInputStream} filled with the content of the outputStream. 1479 * @throws NullPointerException if the {@link ByteArrayOutputStream} is {@code null}. 1480 * @throws IOException if an I/O error occurs. 1481 * @since 2.12 1482 */ 1483 @SuppressWarnings("resource") // streams are closed by the caller. 1484 public static QueueInputStream copy(final java.io.ByteArrayOutputStream outputStream) throws IOException { 1485 Objects.requireNonNull(outputStream, "outputStream"); 1486 final QueueInputStream in = new QueueInputStream(); 1487 outputStream.writeTo(in.newQueueOutputStream()); 1488 return in; 1489 } 1490 1491 /** 1492 * Copies chars from a {@link Reader} to a {@link Appendable}. 1493 * <p> 1494 * This method buffers the input internally, so there is no need to use a 1495 * {@link BufferedReader}. 1496 * </p> 1497 * <p> 1498 * Large streams (over 2GB) will return a chars copied value of 1499 * {@code -1} after the copy has completed since the correct 1500 * number of chars cannot be returned as an int. For large streams 1501 * use the {@link #copyLarge(Reader, Writer)} method. 1502 * </p> 1503 * 1504 * @param reader the {@link Reader} to read. 1505 * @param output the {@link Appendable} to write to. 1506 * @return the number of characters copied, or -1 if > Integer.MAX_VALUE. 1507 * @throws NullPointerException if the input or output is null. 1508 * @throws IOException if an I/O error occurs. 1509 * @since 2.7 1510 */ 1511 public static long copy(final Reader reader, final Appendable output) throws IOException { 1512 return copy(reader, output, CharBuffer.allocate(DEFAULT_BUFFER_SIZE)); 1513 } 1514 1515 /** 1516 * Copies chars from a {@link Reader} to an {@link Appendable}. 1517 * <p> 1518 * This method uses the provided buffer, so there is no need to use a 1519 * {@link BufferedReader}. 1520 * </p> 1521 * 1522 * @param reader the {@link Reader} to read. 1523 * @param output the {@link Appendable} to write to. 1524 * @param buffer the buffer to be used for the copy. 1525 * @return the number of characters copied. 1526 * @throws NullPointerException if the input or output is null. 1527 * @throws IOException if an I/O error occurs. 1528 * @since 2.7 1529 */ 1530 public static long copy(final Reader reader, final Appendable output, final CharBuffer buffer) throws IOException { 1531 long count = 0; 1532 int n; 1533 while (EOF != (n = reader.read(buffer))) { 1534 buffer.flip(); 1535 output.append(buffer, 0, n); 1536 count += n; 1537 } 1538 return count; 1539 } 1540 1541 /** 1542 * Copies chars from a {@link Reader} to bytes on an {@link OutputStream} using the the virtual machine's {@linkplain Charset#defaultCharset() default 1543 * charset}, and calling flush. 1544 * <p> 1545 * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. 1546 * </p> 1547 * <p> 1548 * Due to the implementation of OutputStreamWriter, this method performs a flush. 1549 * </p> 1550 * <p> 1551 * This method uses {@link OutputStreamWriter}. 1552 * </p> 1553 * 1554 * @param reader the {@link Reader} to read. 1555 * @param output the {@link OutputStream} to write to. 1556 * @throws NullPointerException if the input or output is null. 1557 * @throws IOException if an I/O error occurs. 1558 * @since 1.1 1559 * @deprecated Use {@link #copy(Reader, OutputStream, Charset)} instead 1560 */ 1561 @Deprecated 1562 public static void copy(final Reader reader, final OutputStream output) throws IOException { 1563 copy(reader, output, Charset.defaultCharset()); 1564 } 1565 1566 /** 1567 * Copies chars from a {@link Reader} to bytes on an {@link OutputStream} using the specified character encoding, and calling flush. 1568 * <p> 1569 * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. 1570 * </p> 1571 * <p> 1572 * Due to the implementation of OutputStreamWriter, this method performs a flush. 1573 * </p> 1574 * <p> 1575 * This method uses {@link OutputStreamWriter}. 1576 * </p> 1577 * 1578 * @param reader the {@link Reader} to read. 1579 * @param output the {@link OutputStream} to write to. 1580 * @param outputCharset the charset to use for the OutputStream, null means platform default. 1581 * @throws NullPointerException if the input or output is null. 1582 * @throws IOException if an I/O error occurs. 1583 * @since 2.3 1584 */ 1585 public static void copy(final Reader reader, final OutputStream output, final Charset outputCharset) throws IOException { 1586 final OutputStreamWriter writer = new OutputStreamWriter(output, Charsets.toCharset(outputCharset)); 1587 copy(reader, writer); 1588 // XXX Unless anyone is planning on rewriting OutputStreamWriter, 1589 // we have to flush here. 1590 writer.flush(); 1591 } 1592 1593 /** 1594 * Copies chars from a {@link Reader} to bytes on an {@link OutputStream} using the specified character encoding, and calling flush. 1595 * <p> 1596 * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. 1597 * </p> 1598 * <p> 1599 * Character encoding names can be found at <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 1600 * </p> 1601 * <p> 1602 * Due to the implementation of OutputStreamWriter, this method performs a flush. 1603 * </p> 1604 * <p> 1605 * This method uses {@link OutputStreamWriter}. 1606 * </p> 1607 * 1608 * @param reader the {@link Reader} to read. 1609 * @param output the {@link OutputStream} to write to. 1610 * @param outputCharsetName the name of the requested charset for the OutputStream, null means platform default. 1611 * @throws NullPointerException if the input or output is null. 1612 * @throws IOException if an I/O error occurs. 1613 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 1614 * @since 1.1 1615 */ 1616 public static void copy(final Reader reader, final OutputStream output, final String outputCharsetName) throws IOException { 1617 copy(reader, output, Charsets.toCharset(outputCharsetName)); 1618 } 1619 1620 /** 1621 * Copies chars from a {@link Reader} to a {@link Writer}. 1622 * <p> 1623 * This method buffers the input internally, so there is no need to use a 1624 * {@link BufferedReader}. 1625 * </p> 1626 * <p> 1627 * Large streams (over 2GB) will return a chars copied value of 1628 * {@code -1} after the copy has completed since the correct 1629 * number of chars cannot be returned as an int. For large streams 1630 * use the {@link #copyLarge(Reader, Writer)} method. 1631 * </p> 1632 * 1633 * @param reader the {@link Reader} to read. 1634 * @param writer the {@link Writer} to write. 1635 * @return the number of characters copied, or -1 if > Integer.MAX_VALUE. 1636 * @throws NullPointerException if the input or output is null. 1637 * @throws IOException if an I/O error occurs. 1638 * @since 1.1 1639 */ 1640 public static int copy(final Reader reader, final Writer writer) throws IOException { 1641 final long count = copyLarge(reader, writer); 1642 if (count > Integer.MAX_VALUE) { 1643 return EOF; 1644 } 1645 return (int) count; 1646 } 1647 1648 /** 1649 * Copies bytes from a {@link URL} to an {@link OutputStream}. 1650 * <p> 1651 * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. 1652 * </p> 1653 * <p> 1654 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. 1655 * </p> 1656 * 1657 * @param url the {@link URL} to read. 1658 * @param file the {@link OutputStream} to write. 1659 * @return the number of bytes copied. 1660 * @throws NullPointerException if the URL is {@code null}. 1661 * @throws NullPointerException if the OutputStream is {@code null}. 1662 * @throws IOException if an I/O error occurs. 1663 * @since 2.9.0 1664 */ 1665 public static long copy(final URL url, final File file) throws IOException { 1666 try (OutputStream outputStream = Files.newOutputStream(Objects.requireNonNull(file, "file").toPath())) { 1667 return copy(url, outputStream); 1668 } 1669 } 1670 1671 /** 1672 * Copies bytes from a {@link URL} to an {@link OutputStream}. 1673 * <p> 1674 * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. 1675 * </p> 1676 * <p> 1677 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. 1678 * </p> 1679 * 1680 * @param url the {@link URL} to read. 1681 * @param outputStream the {@link OutputStream} to write. 1682 * @return the number of bytes copied. 1683 * @throws NullPointerException if the URL is {@code null}. 1684 * @throws NullPointerException if the OutputStream is {@code null}. 1685 * @throws IOException if an I/O error occurs. 1686 * @since 2.9.0 1687 */ 1688 public static long copy(final URL url, final OutputStream outputStream) throws IOException { 1689 try (InputStream inputStream = Objects.requireNonNull(url, "url").openStream()) { 1690 return copyLarge(inputStream, outputStream); 1691 } 1692 } 1693 1694 /** 1695 * Copies bytes from a large (over 2GB) {@link InputStream} to an 1696 * {@link OutputStream}. 1697 * <p> 1698 * This method buffers the input internally, so there is no need to use a 1699 * {@link BufferedInputStream}. 1700 * </p> 1701 * <p> 1702 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. 1703 * </p> 1704 * 1705 * @param inputStream the {@link InputStream} to read. 1706 * @param outputStream the {@link OutputStream} to write. 1707 * @return the number of bytes copied. 1708 * @throws NullPointerException if the InputStream is {@code null}. 1709 * @throws NullPointerException if the OutputStream is {@code null}. 1710 * @throws IOException if an I/O error occurs. 1711 * @since 1.3 1712 */ 1713 public static long copyLarge(final InputStream inputStream, final OutputStream outputStream) 1714 throws IOException { 1715 return copy(inputStream, outputStream, DEFAULT_BUFFER_SIZE); 1716 } 1717 1718 /** 1719 * Copies bytes from a large (over 2GB) {@link InputStream} to an 1720 * {@link OutputStream}. 1721 * <p> 1722 * This method uses the provided buffer, so there is no need to use a 1723 * {@link BufferedInputStream}. 1724 * </p> 1725 * 1726 * @param inputStream the {@link InputStream} to read. 1727 * @param outputStream the {@link OutputStream} to write. 1728 * @param buffer the buffer to use for the copy 1729 * @return the number of bytes copied. 1730 * @throws NullPointerException if the InputStream is {@code null}. 1731 * @throws NullPointerException if the OutputStream is {@code null}. 1732 * @throws IOException if an I/O error occurs. 1733 * @since 2.2 1734 */ 1735 @SuppressWarnings("resource") // streams are closed by the caller. 1736 public static long copyLarge(final InputStream inputStream, final OutputStream outputStream, final byte[] buffer) 1737 throws IOException { 1738 Objects.requireNonNull(inputStream, "inputStream"); 1739 Objects.requireNonNull(outputStream, "outputStream"); 1740 long count = 0; 1741 int n; 1742 while (EOF != (n = inputStream.read(buffer))) { 1743 outputStream.write(buffer, 0, n); 1744 count += n; 1745 } 1746 return count; 1747 } 1748 1749 /** 1750 * Copies some or all bytes from a large (over 2GB) {@link InputStream} to an 1751 * {@link OutputStream}, optionally skipping input bytes. 1752 * <p> 1753 * This method buffers the input internally, so there is no need to use a 1754 * {@link BufferedInputStream}. 1755 * </p> 1756 * <p> 1757 * Note that the implementation uses {@link #skip(InputStream, long)}. 1758 * This means that the method may be considerably less efficient than using the actual skip implementation, 1759 * this is done to guarantee that the correct number of characters are skipped. 1760 * </p> 1761 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. 1762 * 1763 * @param input the {@link InputStream} to read. 1764 * @param output the {@link OutputStream} to write. 1765 * @param inputOffset number of bytes to skip from input before copying, these bytes are ignored. 1766 * @param length number of bytes to copy. 1767 * @return the number of bytes copied. 1768 * @throws NullPointerException if the input or output is null. 1769 * @throws IOException if an I/O error occurs. 1770 * @since 2.2 1771 */ 1772 public static long copyLarge(final InputStream input, final OutputStream output, final long inputOffset, final long length) throws IOException { 1773 try (ScratchBytes scratch = ScratchBytes.get()) { 1774 return copyLarge(input, output, inputOffset, length, scratch.array()); 1775 } 1776 } 1777 1778 /** 1779 * Copies some or all bytes from a large (over 2GB) {@link InputStream} to an 1780 * {@link OutputStream}, optionally skipping input bytes. 1781 * <p> 1782 * This method uses the provided buffer, so there is no need to use a 1783 * {@link BufferedInputStream}. 1784 * </p> 1785 * <p> 1786 * Note that the implementation uses {@link #skip(InputStream, long)}. 1787 * This means that the method may be considerably less efficient than using the actual skip implementation, 1788 * this is done to guarantee that the correct number of characters are skipped. 1789 * </p> 1790 * 1791 * @param input the {@link InputStream} to read. 1792 * @param output the {@link OutputStream} to write. 1793 * @param inputOffset number of bytes to skip from input before copying, these bytes are ignored. 1794 * @param length number of bytes to copy. 1795 * @param buffer the buffer to use for the copy. 1796 * @return the number of bytes copied. 1797 * @throws NullPointerException if the input or output is null. 1798 * @throws IOException if an I/O error occurs. 1799 * @since 2.2 1800 */ 1801 public static long copyLarge(final InputStream input, final OutputStream output, 1802 final long inputOffset, final long length, final byte[] buffer) throws IOException { 1803 if (inputOffset > 0) { 1804 skipFully(input, inputOffset); 1805 } 1806 if (length == 0) { 1807 return 0; 1808 } 1809 final int bufferLength = buffer.length; 1810 int bytesToRead = bufferLength; 1811 if (length > 0 && length < bufferLength) { 1812 bytesToRead = (int) length; 1813 } 1814 int read; 1815 long totalRead = 0; 1816 while (bytesToRead > 0 && EOF != (read = input.read(buffer, 0, bytesToRead))) { 1817 output.write(buffer, 0, read); 1818 totalRead += read; 1819 if (length > 0) { // only adjust length if not reading to the end 1820 // Note the cast must work because buffer.length is an integer 1821 bytesToRead = (int) Math.min(length - totalRead, bufferLength); 1822 } 1823 } 1824 return totalRead; 1825 } 1826 1827 /** 1828 * Copies chars from a large (over 2GB) {@link Reader} to a {@link Writer}. 1829 * <p> 1830 * This method buffers the input internally, so there is no need to use a 1831 * {@link BufferedReader}. 1832 * </p> 1833 * <p> 1834 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. 1835 * </p> 1836 * 1837 * @param reader the {@link Reader} to source. 1838 * @param writer the {@link Writer} to target. 1839 * @return the number of characters copied. 1840 * @throws NullPointerException if the input or output is null. 1841 * @throws IOException if an I/O error occurs. 1842 * @since 1.3 1843 */ 1844 public static long copyLarge(final Reader reader, final Writer writer) throws IOException { 1845 try (ScratchChars scratch = IOUtils.ScratchChars.get()) { 1846 return copyLarge(reader, writer, scratch.array()); 1847 } 1848 } 1849 1850 /** 1851 * Copies chars from a large (over 2GB) {@link Reader} to a {@link Writer}. 1852 * <p> 1853 * This method uses the provided buffer, so there is no need to use a 1854 * {@link BufferedReader}. 1855 * </p> 1856 * 1857 * @param reader the {@link Reader} to source. 1858 * @param writer the {@link Writer} to target. 1859 * @param buffer the buffer to be used for the copy 1860 * @return the number of characters copied 1861 * @throws NullPointerException if the input or output is null 1862 * @throws IOException if an I/O error occurs 1863 * @since 2.2 1864 */ 1865 public static long copyLarge(final Reader reader, final Writer writer, final char[] buffer) throws IOException { 1866 long count = 0; 1867 int n; 1868 while (EOF != (n = reader.read(buffer))) { 1869 writer.write(buffer, 0, n); 1870 count += n; 1871 } 1872 return count; 1873 } 1874 1875 /** 1876 * Copies some or all chars from a large (over 2GB) {@link InputStream} to an {@link OutputStream}, optionally skipping input chars. 1877 * <p> 1878 * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. 1879 * </p> 1880 * <p> 1881 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. 1882 * </p> 1883 * 1884 * @param reader the {@link Reader} to read. 1885 * @param writer the {@link Writer} to write to. 1886 * @param inputOffset number of chars to skip from input before copying -ve values are ignored. 1887 * @param length number of chars to copy. -ve means all. 1888 * @return the number of chars copied. 1889 * @throws NullPointerException if the input or output is null. 1890 * @throws IOException if an I/O error occurs. 1891 * @since 2.2 1892 */ 1893 public static long copyLarge(final Reader reader, final Writer writer, final long inputOffset, final long length) throws IOException { 1894 try (ScratchChars scratch = IOUtils.ScratchChars.get()) { 1895 return copyLarge(reader, writer, inputOffset, length, scratch.array()); 1896 } 1897 } 1898 1899 /** 1900 * Copies some or all chars from a large (over 2GB) {@link InputStream} to an {@link OutputStream}, optionally skipping input chars. 1901 * <p> 1902 * This method uses the provided buffer, so there is no need to use a {@link BufferedReader}. 1903 * </p> 1904 * 1905 * @param reader the {@link Reader} to read. 1906 * @param writer the {@link Writer} to write to. 1907 * @param inputOffset number of chars to skip from input before copying -ve values are ignored. 1908 * @param length number of chars to copy. -ve means all. 1909 * @param buffer the buffer to be used for the copy. 1910 * @return the number of chars copied. 1911 * @throws NullPointerException if the input or output is null. 1912 * @throws IOException if an I/O error occurs. 1913 * @since 2.2 1914 */ 1915 public static long copyLarge(final Reader reader, final Writer writer, final long inputOffset, final long length, final char[] buffer) throws IOException { 1916 if (inputOffset > 0) { 1917 skipFully(reader, inputOffset); 1918 } 1919 if (length == 0) { 1920 return 0; 1921 } 1922 int bytesToRead = buffer.length; 1923 if (length > 0 && length < buffer.length) { 1924 bytesToRead = (int) length; 1925 } 1926 int read; 1927 long totalRead = 0; 1928 while (bytesToRead > 0 && EOF != (read = reader.read(buffer, 0, bytesToRead))) { 1929 writer.write(buffer, 0, read); 1930 totalRead += read; 1931 if (length > 0) { // only adjust length if not reading to the end 1932 // Note the cast must work because buffer.length is an integer 1933 bytesToRead = (int) Math.min(length - totalRead, buffer.length); 1934 } 1935 } 1936 return totalRead; 1937 } 1938 1939 /** 1940 * Copies up to {@code size} bytes from the given {@link InputStream} into a new {@link UnsynchronizedByteArrayOutputStream}. 1941 * 1942 * @param input The {@link InputStream} to read; must not be {@code null}. 1943 * @param limit The maximum number of bytes to read; must be {@code >= 0}. 1944 * The actual bytes read are validated to equal {@code size}. 1945 * @param bufferSize The buffer size of the output stream; must be {@code > 0}. 1946 * @return a ByteArrayOutputStream containing the read bytes. 1947 */ 1948 static UnsynchronizedByteArrayOutputStream copyToOutputStream( 1949 final InputStream input, final long limit, final int bufferSize) throws IOException { 1950 try (UnsynchronizedByteArrayOutputStream output = UnsynchronizedByteArrayOutputStream.builder() 1951 .setBufferSize(bufferSize) 1952 .get(); 1953 InputStream boundedInput = BoundedInputStream.builder() 1954 .setMaxCount(limit) 1955 .setPropagateClose(false) 1956 .setInputStream(input) 1957 .get()) { 1958 output.write(boundedInput); 1959 return output; 1960 } 1961 } 1962 1963 /** 1964 * Returns the length of the given array in a null-safe manner. 1965 * 1966 * @param array an array or null. 1967 * @return the array length, or 0 if the given array is null. 1968 * @since 2.7 1969 */ 1970 public static int length(final byte[] array) { 1971 return array == null ? 0 : array.length; 1972 } 1973 1974 /** 1975 * Returns the length of the given array in a null-safe manner. 1976 * 1977 * @param array an array or null. 1978 * @return the array length, or 0 if the given array is null. 1979 * @since 2.7 1980 */ 1981 public static int length(final char[] array) { 1982 return array == null ? 0 : array.length; 1983 } 1984 1985 /** 1986 * Returns the length of the given CharSequence in a null-safe manner. 1987 * 1988 * @param csq a CharSequence or null. 1989 * @return the CharSequence length, or 0 if the given CharSequence is null. 1990 * @since 2.7 1991 */ 1992 public static int length(final CharSequence csq) { 1993 return csq == null ? 0 : csq.length(); 1994 } 1995 1996 /** 1997 * Returns the length of the given array in a null-safe manner. 1998 * 1999 * @param array an array or null. 2000 * @return the array length, or 0 if the given array is null. 2001 * @since 2.7 2002 */ 2003 public static int length(final Object[] array) { 2004 return array == null ? 0 : array.length; 2005 } 2006 2007 /** 2008 * Returns an Iterator for the lines in an {@link InputStream}, using 2009 * the character encoding specified (or default encoding if null). 2010 * <p> 2011 * {@link LineIterator} holds a reference to the open 2012 * {@link InputStream} specified here. When you have finished with 2013 * the iterator you should close the stream to free internal resources. 2014 * This can be done by using a try-with-resources block, closing the stream directly, or by calling 2015 * {@link LineIterator#close()}. 2016 * </p> 2017 * <p> 2018 * The recommended usage pattern is: 2019 * </p> 2020 * <pre> 2021 * try { 2022 * LineIterator it = IOUtils.lineIterator(stream, charset); 2023 * while (it.hasNext()) { 2024 * String line = it.nextLine(); 2025 * /// do something with line 2026 * } 2027 * } finally { 2028 * IOUtils.closeQuietly(stream); 2029 * } 2030 * </pre> 2031 * 2032 * @param input the {@link InputStream} to read, not null. 2033 * @param charset the charset to use, null means platform default. 2034 * @return an Iterator of the lines in the reader, never null. 2035 * @throws IllegalArgumentException if the input is null. 2036 * @since 2.3 2037 */ 2038 public static LineIterator lineIterator(final InputStream input, final Charset charset) { 2039 return new LineIterator(new InputStreamReader(input, Charsets.toCharset(charset))); 2040 } 2041 2042 /** 2043 * Returns an Iterator for the lines in an {@link InputStream}, using 2044 * the character encoding specified (or default encoding if null). 2045 * <p> 2046 * {@link LineIterator} holds a reference to the open 2047 * {@link InputStream} specified here. When you have finished with 2048 * the iterator you should close the stream to free internal resources. 2049 * This can be done by using a try-with-resources block, closing the stream directly, or by calling 2050 * {@link LineIterator#close()}. 2051 * </p> 2052 * <p> 2053 * The recommended usage pattern is: 2054 * </p> 2055 * <pre> 2056 * try { 2057 * LineIterator it = IOUtils.lineIterator(stream, StandardCharsets.UTF_8.name()); 2058 * while (it.hasNext()) { 2059 * String line = it.nextLine(); 2060 * /// do something with line 2061 * } 2062 * } finally { 2063 * IOUtils.closeQuietly(stream); 2064 * } 2065 * </pre> 2066 * 2067 * @param input the {@link InputStream} to read, not null. 2068 * @param charsetName the encoding to use, null means platform default. 2069 * @return an Iterator of the lines in the reader, never null. 2070 * @throws IllegalArgumentException if the input is null. 2071 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 2072 * @since 1.2 2073 */ 2074 public static LineIterator lineIterator(final InputStream input, final String charsetName) { 2075 return lineIterator(input, Charsets.toCharset(charsetName)); 2076 } 2077 2078 /** 2079 * Returns an Iterator for the lines in a {@link Reader}. 2080 * <p> 2081 * {@link LineIterator} holds a reference to the open 2082 * {@link Reader} specified here. When you have finished with the 2083 * iterator you should close the reader to free internal resources. 2084 * This can be done by using a try-with-resources block, closing the reader directly, or by calling 2085 * {@link LineIterator#close()}. 2086 * </p> 2087 * <p> 2088 * The recommended usage pattern is: 2089 * </p> 2090 * <pre> 2091 * try { 2092 * LineIterator it = IOUtils.lineIterator(reader); 2093 * while (it.hasNext()) { 2094 * String line = it.nextLine(); 2095 * /// do something with line 2096 * } 2097 * } finally { 2098 * IOUtils.closeQuietly(reader); 2099 * } 2100 * </pre> 2101 * 2102 * @param reader the {@link Reader} to read, not null. 2103 * @return an Iterator of the lines in the reader, never null. 2104 * @throws NullPointerException if the reader is null. 2105 * @since 1.2 2106 */ 2107 public static LineIterator lineIterator(final Reader reader) { 2108 return new LineIterator(reader); 2109 } 2110 2111 /** 2112 * Reads bytes from an input stream. 2113 * <p> 2114 * This implementation guarantees that it will read as many bytes 2115 * as possible before giving up; this may not always be the case for 2116 * subclasses of {@link InputStream}. 2117 * </p> 2118 * 2119 * @param input where to read input from. 2120 * @param buffer destination. 2121 * @return actual length read; may be less than requested if EOF was reached. 2122 * @throws NullPointerException if {@code input} or {@code buffer} is null. 2123 * @throws IOException if a read error occurs. 2124 * @since 2.2 2125 */ 2126 public static int read(final InputStream input, final byte[] buffer) throws IOException { 2127 return read(input, buffer, 0, buffer.length); 2128 } 2129 2130 /** 2131 * Reads bytes from an input stream. 2132 * <p> 2133 * This implementation guarantees that it will read as many bytes 2134 * as possible before giving up; this may not always be the case for 2135 * subclasses of {@link InputStream}. 2136 * </p> 2137 * 2138 * @param input where to read input. 2139 * @param buffer destination. 2140 * @param offset initial offset into buffer. 2141 * @param length length to read, must be >= 0. 2142 * @return actual length read; may be less than requested if EOF was reached. 2143 * @throws NullPointerException if {@code input} or {@code buffer} is null. 2144 * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if 2145 * {@code offset + length} is greater than {@code buffer.length}. 2146 * @throws IOException if a read error occurs. 2147 * @since 2.2 2148 */ 2149 public static int read(final InputStream input, final byte[] buffer, final int offset, final int length) 2150 throws IOException { 2151 checkFromIndexSize(buffer, offset, length); 2152 int remaining = length; 2153 while (remaining > 0) { 2154 final int location = length - remaining; 2155 final int count = input.read(buffer, offset + location, remaining); 2156 if (EOF == count) { 2157 break; 2158 } 2159 remaining -= count; 2160 } 2161 return length - remaining; 2162 } 2163 2164 /** 2165 * Reads bytes from a ReadableByteChannel. 2166 * <p> 2167 * This implementation guarantees that it will read as many bytes 2168 * as possible before giving up; this may not always be the case for 2169 * subclasses of {@link ReadableByteChannel}. 2170 * </p> 2171 * 2172 * @param input the byte channel to read. 2173 * @param buffer byte buffer destination. 2174 * @return the actual length read; may be less than requested if EOF was reached. 2175 * @throws IOException if a read error occurs. 2176 * @since 2.5 2177 */ 2178 public static int read(final ReadableByteChannel input, final ByteBuffer buffer) throws IOException { 2179 final int length = buffer.remaining(); 2180 while (buffer.remaining() > 0) { 2181 final int count = input.read(buffer); 2182 if (EOF == count) { // EOF 2183 break; 2184 } 2185 } 2186 return length - buffer.remaining(); 2187 } 2188 2189 /** 2190 * Reads characters from an input character stream. 2191 * <p> 2192 * This implementation guarantees that it will read as many characters 2193 * as possible before giving up; this may not always be the case for 2194 * subclasses of {@link Reader}. 2195 * </p> 2196 * 2197 * @param reader where to read input from. 2198 * @param buffer destination. 2199 * @return actual length read; may be less than requested if EOF was reached. 2200 * @throws IOException if a read error occurs. 2201 * @since 2.2 2202 */ 2203 public static int read(final Reader reader, final char[] buffer) throws IOException { 2204 return read(reader, buffer, 0, buffer.length); 2205 } 2206 2207 /** 2208 * Reads characters from an input character stream. 2209 * <p> 2210 * This implementation guarantees that it will read as many characters 2211 * as possible before giving up; this may not always be the case for 2212 * subclasses of {@link Reader}. 2213 * </p> 2214 * 2215 * @param reader where to read input from. 2216 * @param buffer destination. 2217 * @param offset initial offset into buffer. 2218 * @param length length to read, must be >= 0. 2219 * @return actual length read; may be less than requested if EOF was reached. 2220 * @throws NullPointerException if {@code reader} or {@code buffer} is null. 2221 * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if 2222 * {@code offset + length} is greater than {@code buffer.length}. 2223 * @throws IOException if a read error occurs. 2224 * @since 2.2 2225 */ 2226 public static int read(final Reader reader, final char[] buffer, final int offset, final int length) 2227 throws IOException { 2228 checkFromIndexSize(buffer, offset, length); 2229 int remaining = length; 2230 while (remaining > 0) { 2231 final int location = length - remaining; 2232 final int count = reader.read(buffer, offset + location, remaining); 2233 if (EOF == count) { // EOF 2234 break; 2235 } 2236 remaining -= count; 2237 } 2238 return length - remaining; 2239 } 2240 2241 /** 2242 * Reads the requested number of bytes or fail if there are not enough left. 2243 * <p> 2244 * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may 2245 * not read as many bytes as requested (most likely because of reaching EOF). 2246 * </p> 2247 * 2248 * @param input where to read input from. 2249 * @param buffer destination. 2250 * @throws NullPointerException if {@code input} or {@code buffer} is null. 2251 * @throws EOFException if the number of bytes read was incorrect. 2252 * @throws IOException if there is a problem reading the file. 2253 * @since 2.2 2254 */ 2255 public static void readFully(final InputStream input, final byte[] buffer) throws IOException { 2256 readFully(input, buffer, 0, buffer.length); 2257 } 2258 2259 /** 2260 * Reads the requested number of bytes or fail if there are not enough left. 2261 * <p> 2262 * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may 2263 * not read as many bytes as requested (most likely because of reaching EOF). 2264 * </p> 2265 * 2266 * @param input where to read input from. 2267 * @param buffer destination. 2268 * @param offset initial offset into buffer. 2269 * @param length length to read, must be >= 0. 2270 * @throws NullPointerException if {@code input} or {@code buffer} is null. 2271 * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if 2272 * {@code offset + length} is greater than {@code buffer.length}. 2273 * @throws EOFException if the number of bytes read was incorrect. 2274 * @throws IOException if there is a problem reading the file. 2275 * @since 2.2 2276 */ 2277 public static void readFully(final InputStream input, final byte[] buffer, final int offset, final int length) 2278 throws IOException { 2279 final int actual = read(input, buffer, offset, length); 2280 if (actual != length) { 2281 throw new EOFException("Length to read: " + length + " actual: " + actual); 2282 } 2283 } 2284 2285 /** 2286 * Reads the requested number of bytes or fail if there are not enough left. 2287 * <p> 2288 * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may 2289 * not read as many bytes as requested (most likely because of reaching EOF). 2290 * </p> 2291 * 2292 * @param input where to read input from. 2293 * @param length length to read, must be >= 0. 2294 * @return the bytes read from input. 2295 * @throws IOException if there is a problem reading the file. 2296 * @throws IllegalArgumentException if length is negative. 2297 * @throws EOFException if the number of bytes read was incorrect. 2298 * @since 2.5 2299 * @deprecated Use {@link #toByteArray(InputStream, int)}. 2300 */ 2301 @Deprecated 2302 public static byte[] readFully(final InputStream input, final int length) throws IOException { 2303 return toByteArray(input, length); 2304 } 2305 2306 /** 2307 * Reads the requested number of bytes or fail if there are not enough left. 2308 * <p> 2309 * This allows for the possibility that {@link ReadableByteChannel#read(ByteBuffer)} may 2310 * not read as many bytes as requested (most likely because of reaching EOF). 2311 * </p> 2312 * 2313 * @param input the byte channel to read. 2314 * @param buffer byte buffer destination. 2315 * @throws IOException if there is a problem reading the file. 2316 * @throws EOFException if the number of bytes read was incorrect. 2317 * @since 2.5 2318 */ 2319 public static void readFully(final ReadableByteChannel input, final ByteBuffer buffer) throws IOException { 2320 final int expected = buffer.remaining(); 2321 final int actual = read(input, buffer); 2322 if (actual != expected) { 2323 throw new EOFException("Length to read: " + expected + " actual: " + actual); 2324 } 2325 } 2326 2327 /** 2328 * Reads the requested number of characters or fail if there are not enough left. 2329 * <p> 2330 * This allows for the possibility that {@link Reader#read(char[], int, int)} may 2331 * not read as many characters as requested (most likely because of reaching EOF). 2332 * </p> 2333 * 2334 * @param reader where to read input from. 2335 * @param buffer destination. 2336 * @throws NullPointerException if {@code reader} or {@code buffer} is null. 2337 * @throws EOFException if the number of characters read was incorrect. 2338 * @throws IOException if there is a problem reading the file. 2339 * @since 2.2 2340 */ 2341 public static void readFully(final Reader reader, final char[] buffer) throws IOException { 2342 readFully(reader, buffer, 0, buffer.length); 2343 } 2344 2345 /** 2346 * Reads the requested number of characters or fail if there are not enough left. 2347 * <p> 2348 * This allows for the possibility that {@link Reader#read(char[], int, int)} may 2349 * not read as many characters as requested (most likely because of reaching EOF). 2350 * </p> 2351 * 2352 * @param reader where to read input from. 2353 * @param buffer destination. 2354 * @param offset initial offset into buffer. 2355 * @param length length to read, must be >= 0. 2356 * @throws NullPointerException if {@code reader} or {@code buffer} is null. 2357 * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if 2358 * {@code offset + length} is greater than {@code buffer.length}. 2359 * @throws EOFException if the number of characters read was incorrect. 2360 * @throws IOException if there is a problem reading the file. 2361 * @since 2.2 2362 */ 2363 public static void readFully(final Reader reader, final char[] buffer, final int offset, final int length) 2364 throws IOException { 2365 final int actual = read(reader, buffer, offset, length); 2366 if (actual != length) { 2367 throw new EOFException("Length to read: " + length + " actual: " + actual); 2368 } 2369 } 2370 2371 /** 2372 * Gets the contents of a {@link CharSequence} as a list of Strings, one entry per line. 2373 * 2374 * @param csq the {@link CharSequence} to read, not null. 2375 * @return the list of Strings, never null. 2376 * @throws UncheckedIOException if an I/O error occurs. 2377 * @since 2.18.0 2378 */ 2379 public static List<String> readLines(final CharSequence csq) throws UncheckedIOException { 2380 try (CharSequenceReader reader = new CharSequenceReader(csq)) { 2381 return readLines(reader); 2382 } 2383 } 2384 2385 /** 2386 * Gets the contents of an {@link InputStream} as a list of Strings, 2387 * one entry per line, using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. 2388 * <p> 2389 * This method buffers the input internally, so there is no need to use a 2390 * {@link BufferedInputStream}. 2391 * </p> 2392 * 2393 * @param input the {@link InputStream} to read, not null. 2394 * @return the list of Strings, never null. 2395 * @throws NullPointerException if the input is null. 2396 * @throws UncheckedIOException if an I/O error occurs. 2397 * @since 1.1 2398 * @deprecated Use {@link #readLines(InputStream, Charset)} instead 2399 */ 2400 @Deprecated 2401 public static List<String> readLines(final InputStream input) throws UncheckedIOException { 2402 return readLines(input, Charset.defaultCharset()); 2403 } 2404 2405 /** 2406 * Gets the contents of an {@link InputStream} as a list of Strings, 2407 * one entry per line, using the specified character encoding. 2408 * <p> 2409 * This method buffers the input internally, so there is no need to use a 2410 * {@link BufferedInputStream}. 2411 * </p> 2412 * 2413 * @param input the {@link InputStream} to read, not null. 2414 * @param charset the charset to use, null means platform default. 2415 * @return the list of Strings, never null. 2416 * @throws NullPointerException if the input is null. 2417 * @throws UncheckedIOException if an I/O error occurs. 2418 * @since 2.3 2419 */ 2420 public static List<String> readLines(final InputStream input, final Charset charset) throws UncheckedIOException { 2421 return readLines(new InputStreamReader(input, Charsets.toCharset(charset))); 2422 } 2423 2424 /** 2425 * Gets the contents of an {@link InputStream} as a list of Strings, 2426 * one entry per line, using the specified character encoding. 2427 * <p> 2428 * Character encoding names can be found at 2429 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 2430 * </p> 2431 * <p> 2432 * This method buffers the input internally, so there is no need to use a 2433 * {@link BufferedInputStream}. 2434 * </p> 2435 * 2436 * @param input the {@link InputStream} to read, not null. 2437 * @param charsetName the name of the requested charset, null means platform default. 2438 * @return the list of Strings, never null. 2439 * @throws NullPointerException if the input is null. 2440 * @throws UncheckedIOException if an I/O error occurs. 2441 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 2442 * @since 1.1 2443 */ 2444 public static List<String> readLines(final InputStream input, final String charsetName) throws UncheckedIOException { 2445 return readLines(input, Charsets.toCharset(charsetName)); 2446 } 2447 2448 /** 2449 * Gets the contents of a {@link Reader} as a list of Strings, 2450 * one entry per line. 2451 * <p> 2452 * This method buffers the input internally, so there is no need to use a 2453 * {@link BufferedReader}. 2454 * </p> 2455 * 2456 * @param reader the {@link Reader} to read, not null. 2457 * @return the list of Strings, never null. 2458 * @throws NullPointerException if the input is null. 2459 * @throws UncheckedIOException if an I/O error occurs. 2460 * @since 1.1 2461 */ 2462 @SuppressWarnings("resource") // reader wraps input and is the responsibility of the caller. 2463 public static List<String> readLines(final Reader reader) throws UncheckedIOException { 2464 return toBufferedReader(reader).lines().collect(Collectors.toList()); 2465 } 2466 2467 /** 2468 * Gets the contents of a resource as a byte array. 2469 * <p> 2470 * Delegates to {@link #resourceToByteArray(String, ClassLoader) resourceToByteArray(String, null)}. 2471 * </p> 2472 * 2473 * @param name The resource name. 2474 * @return the requested byte array. 2475 * @throws IOException if an I/O error occurs or the resource is not found. 2476 * @see #resourceToByteArray(String, ClassLoader) 2477 * @since 2.6 2478 */ 2479 public static byte[] resourceToByteArray(final String name) throws IOException { 2480 return resourceToByteArray(name, null); 2481 } 2482 2483 /** 2484 * Gets the contents of a resource as a byte array. 2485 * <p> 2486 * Delegates to {@link #resourceToURL(String, ClassLoader)}. 2487 * </p> 2488 * 2489 * @param name The resource name. 2490 * @param classLoader the class loader that the resolution of the resource is delegated to. 2491 * @return the requested byte array. 2492 * @throws IOException if an I/O error occurs or the resource is not found. 2493 * @see #resourceToURL(String, ClassLoader) 2494 * @since 2.6 2495 */ 2496 public static byte[] resourceToByteArray(final String name, final ClassLoader classLoader) throws IOException { 2497 return toByteArray(resourceToURL(name, classLoader)); 2498 } 2499 2500 /** 2501 * Gets the contents of a resource as a String using the specified character encoding. 2502 * <p> 2503 * Delegates to {@link #resourceToString(String, Charset, ClassLoader) resourceToString(String, Charset, null)}. 2504 * </p> 2505 * 2506 * @param name The resource name. 2507 * @param charset the charset to use, null means platform default. 2508 * @return the requested String. 2509 * @throws IOException if an I/O error occurs or the resource is not found. 2510 * @see #resourceToString(String, Charset, ClassLoader) 2511 * @since 2.6 2512 */ 2513 public static String resourceToString(final String name, final Charset charset) throws IOException { 2514 return resourceToString(name, charset, null); 2515 } 2516 2517 /** 2518 * Gets the contents of a resource as a String using the specified character encoding. 2519 * <p> 2520 * Delegates to {@link #resourceToURL(String, ClassLoader)}. 2521 * </p> 2522 * 2523 * @param name The resource name. 2524 * @param charset the Charset to use, null means platform default. 2525 * @param classLoader the class loader that the resolution of the resource is delegated to. 2526 * @return the requested String. 2527 * @throws IOException if an I/O error occurs. 2528 * @see #resourceToURL(String, ClassLoader) 2529 * @since 2.6 2530 */ 2531 public static String resourceToString(final String name, final Charset charset, final ClassLoader classLoader) throws IOException { 2532 return toString(resourceToURL(name, classLoader), charset); 2533 } 2534 2535 /** 2536 * Gets a URL pointing to the given resource. 2537 * <p> 2538 * Delegates to {@link #resourceToURL(String, ClassLoader) resourceToURL(String, null)}. 2539 * </p> 2540 * 2541 * @param name The resource name. 2542 * @return A URL object for reading the resource. 2543 * @throws IOException if the resource is not found. 2544 * @since 2.6 2545 */ 2546 public static URL resourceToURL(final String name) throws IOException { 2547 return resourceToURL(name, null); 2548 } 2549 2550 /** 2551 * Gets a URL pointing to the given resource. 2552 * <p> 2553 * If the {@code classLoader} is not null, call {@link ClassLoader#getResource(String)}, otherwise call 2554 * {@link Class#getResource(String) IOUtils.class.getResource(name)}. 2555 * </p> 2556 * 2557 * @param name The resource name. 2558 * @param classLoader Delegate to this class loader if not null. 2559 * @return A URL object for reading the resource. 2560 * @throws IOException if the resource is not found. 2561 * @since 2.6 2562 */ 2563 public static URL resourceToURL(final String name, final ClassLoader classLoader) throws IOException { 2564 // What about the thread context class loader? 2565 // What about the system class loader? 2566 final URL resource = classLoader == null ? IOUtils.class.getResource(name) : classLoader.getResource(name); 2567 if (resource == null) { 2568 throw new IOException("Resource not found: " + name); 2569 } 2570 return resource; 2571 } 2572 2573 /** 2574 * Skips bytes from an input byte stream. 2575 * <p> 2576 * This implementation guarantees that it will read as many bytes as possible before giving up; this may not always be the case for skip() implementations 2577 * in subclasses of {@link InputStream}. 2578 * </p> 2579 * <p> 2580 * Note that the implementation uses {@link InputStream#read(byte[], int, int)} rather than delegating to {@link InputStream#skip(long)}. This means that 2581 * the method may be considerably less efficient than using the actual skip implementation, this is done to guarantee that the correct number of bytes are 2582 * skipped. 2583 * </p> 2584 * 2585 * @param input byte stream to skip. 2586 * @param skip number of bytes to skip. 2587 * @return number of bytes actually skipped. 2588 * @throws IOException if there is a problem reading the file. 2589 * @throws IllegalArgumentException if toSkip is negative. 2590 * @see InputStream#skip(long) 2591 * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a> 2592 * @since 2.0 2593 */ 2594 public static long skip(final InputStream input, final long skip) throws IOException { 2595 try (ScratchBytes scratch = ScratchBytes.get()) { 2596 return skip(input, skip, scratch::array); 2597 } 2598 } 2599 2600 /** 2601 * Skips bytes from an input byte stream. 2602 * <p> 2603 * Intended for special cases when customization of the temporary buffer is needed because, for example, a nested input stream has requirements for the 2604 * bytes read. For example, when using {@link InflaterInputStream}s from multiple threads. 2605 * </p> 2606 * <p> 2607 * This implementation guarantees that it will read as many bytes as possible before giving up; this may not always be the case for skip() implementations 2608 * in subclasses of {@link InputStream}. 2609 * </p> 2610 * <p> 2611 * Note that the implementation uses {@link InputStream#read(byte[], int, int)} rather than delegating to {@link InputStream#skip(long)}. This means that 2612 * the method may be considerably less efficient than using the actual skip implementation, this is done to guarantee that the correct number of bytes are 2613 * skipped. 2614 * </p> 2615 * 2616 * @param input byte stream to skip. 2617 * @param skip number of bytes to skip. 2618 * @param skipBufferSupplier Supplies the buffer to use for reading. 2619 * @return number of bytes actually skipped. 2620 * @throws IOException if there is a problem reading the file. 2621 * @throws IllegalArgumentException if toSkip is negative. 2622 * @see InputStream#skip(long) 2623 * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a> 2624 * @since 2.14.0 2625 */ 2626 public static long skip(final InputStream input, final long skip, final Supplier<byte[]> skipBufferSupplier) throws IOException { 2627 if (skip < 0) { 2628 throw new IllegalArgumentException("Skip count must be non-negative, actual: " + skip); 2629 } 2630 // 2631 // No need to synchronize access to SCRATCH_BYTE_BUFFER_WO: We don't care if the buffer is written multiple 2632 // times or in parallel since the data is ignored. We reuse the same buffer, if the buffer size were variable or read-write, 2633 // we would need to synch or use a thread local to ensure some other thread safety. 2634 // 2635 long remain = skip; 2636 while (remain > 0) { 2637 final byte[] skipBuffer = skipBufferSupplier.get(); 2638 // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip() 2639 final long n = input.read(skipBuffer, 0, (int) Math.min(remain, skipBuffer.length)); 2640 if (n < 0) { // EOF 2641 break; 2642 } 2643 remain -= n; 2644 } 2645 return skip - remain; 2646 } 2647 2648 /** 2649 * Skips bytes from a ReadableByteChannel. 2650 * This implementation guarantees that it will read as many bytes 2651 * as possible before giving up. 2652 * 2653 * @param input ReadableByteChannel to skip. 2654 * @param toSkip number of bytes to skip. 2655 * @return number of bytes actually skipped. 2656 * @throws IOException if there is a problem reading the ReadableByteChannel. 2657 * @throws IllegalArgumentException if toSkip is negative. 2658 * @since 2.5 2659 */ 2660 public static long skip(final ReadableByteChannel input, final long toSkip) throws IOException { 2661 if (toSkip < 0) { 2662 throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip); 2663 } 2664 final ByteBuffer skipByteBuffer = ByteBuffer.allocate((int) Math.min(toSkip, DEFAULT_BUFFER_SIZE)); 2665 long remain = toSkip; 2666 while (remain > 0) { 2667 skipByteBuffer.position(0); 2668 skipByteBuffer.limit((int) Math.min(remain, DEFAULT_BUFFER_SIZE)); 2669 final int n = input.read(skipByteBuffer); 2670 if (n == EOF) { 2671 break; 2672 } 2673 remain -= n; 2674 } 2675 return toSkip - remain; 2676 } 2677 2678 /** 2679 * Skips characters from an input character stream. 2680 * This implementation guarantees that it will read as many characters 2681 * as possible before giving up; this may not always be the case for 2682 * skip() implementations in subclasses of {@link Reader}. 2683 * <p> 2684 * Note that the implementation uses {@link Reader#read(char[], int, int)} rather 2685 * than delegating to {@link Reader#skip(long)}. 2686 * This means that the method may be considerably less efficient than using the actual skip implementation, 2687 * this is done to guarantee that the correct number of characters are skipped. 2688 * </p> 2689 * 2690 * @param reader character stream to skip. 2691 * @param toSkip number of characters to skip. 2692 * @return number of characters actually skipped. 2693 * @throws IOException if there is a problem reading the file. 2694 * @throws IllegalArgumentException if toSkip is negative. 2695 * @see Reader#skip(long) 2696 * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a> 2697 * @since 2.0 2698 */ 2699 public static long skip(final Reader reader, final long toSkip) throws IOException { 2700 if (toSkip < 0) { 2701 throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip); 2702 } 2703 long remain = toSkip; 2704 try (ScratchChars scratch = IOUtils.ScratchChars.get()) { 2705 final char[] chars = scratch.array(); 2706 while (remain > 0) { 2707 // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip() 2708 final long n = reader.read(chars, 0, (int) Math.min(remain, chars.length)); 2709 if (n < 0) { // EOF 2710 break; 2711 } 2712 remain -= n; 2713 } 2714 } 2715 return toSkip - remain; 2716 } 2717 2718 /** 2719 * Skips the requested number of bytes or fail if there are not enough left. 2720 * <p> 2721 * This allows for the possibility that {@link InputStream#skip(long)} may 2722 * not skip as many bytes as requested (most likely because of reaching EOF). 2723 * </p> 2724 * <p> 2725 * Note that the implementation uses {@link #skip(InputStream, long)}. 2726 * This means that the method may be considerably less efficient than using the actual skip implementation, 2727 * this is done to guarantee that the correct number of characters are skipped. 2728 * </p> 2729 * 2730 * @param input stream to skip. 2731 * @param toSkip the number of bytes to skip. 2732 * @throws IOException if there is a problem reading the file. 2733 * @throws IllegalArgumentException if toSkip is negative. 2734 * @throws EOFException if the number of bytes skipped was incorrect. 2735 * @see InputStream#skip(long) 2736 * @since 2.0 2737 */ 2738 public static void skipFully(final InputStream input, final long toSkip) throws IOException { 2739 final long skipped = skip(input, toSkip); 2740 if (skipped != toSkip) { 2741 throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped); 2742 } 2743 } 2744 2745 /** 2746 * Skips the requested number of bytes or fail if there are not enough left. 2747 * <p> 2748 * Intended for special cases when customization of the temporary buffer is needed because, for example, a nested input stream has requirements for the 2749 * bytes read. For example, when using {@link InflaterInputStream}s from multiple threads. 2750 * </p> 2751 * <p> 2752 * This allows for the possibility that {@link InputStream#skip(long)} may not skip as many bytes as requested (most likely because of reaching EOF). 2753 * </p> 2754 * <p> 2755 * Note that the implementation uses {@link #skip(InputStream, long)}. This means that the method may be considerably less efficient than using the actual 2756 * skip implementation, this is done to guarantee that the correct number of characters are skipped. 2757 * </p> 2758 * 2759 * @param input stream to skip. 2760 * @param toSkip the number of bytes to skip. 2761 * @param skipBufferSupplier Supplies the buffer to use for reading. 2762 * @throws IOException if there is a problem reading the file. 2763 * @throws IllegalArgumentException if toSkip is negative. 2764 * @throws EOFException if the number of bytes skipped was incorrect. 2765 * @see InputStream#skip(long) 2766 * @since 2.14.0 2767 */ 2768 public static void skipFully(final InputStream input, final long toSkip, final Supplier<byte[]> skipBufferSupplier) throws IOException { 2769 if (toSkip < 0) { 2770 throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip); 2771 } 2772 final long skipped = skip(input, toSkip, skipBufferSupplier); 2773 if (skipped != toSkip) { 2774 throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped); 2775 } 2776 } 2777 2778 /** 2779 * Skips the requested number of bytes or fail if there are not enough left. 2780 * 2781 * @param input ReadableByteChannel to skip. 2782 * @param toSkip the number of bytes to skip. 2783 * @throws IOException if there is a problem reading the ReadableByteChannel. 2784 * @throws IllegalArgumentException if toSkip is negative. 2785 * @throws EOFException if the number of bytes skipped was incorrect. 2786 * @since 2.5 2787 */ 2788 public static void skipFully(final ReadableByteChannel input, final long toSkip) throws IOException { 2789 if (toSkip < 0) { 2790 throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip); 2791 } 2792 final long skipped = skip(input, toSkip); 2793 if (skipped != toSkip) { 2794 throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped); 2795 } 2796 } 2797 2798 /** 2799 * Skips the requested number of characters or fail if there are not enough left. 2800 * <p> 2801 * This allows for the possibility that {@link Reader#skip(long)} may 2802 * not skip as many characters as requested (most likely because of reaching EOF). 2803 * </p> 2804 * <p> 2805 * Note that the implementation uses {@link #skip(Reader, long)}. 2806 * This means that the method may be considerably less efficient than using the actual skip implementation, 2807 * this is done to guarantee that the correct number of characters are skipped. 2808 * </p> 2809 * 2810 * @param reader stream to skip. 2811 * @param toSkip the number of characters to skip. 2812 * @throws IOException if there is a problem reading the file. 2813 * @throws IllegalArgumentException if toSkip is negative. 2814 * @throws EOFException if the number of characters skipped was incorrect. 2815 * @see Reader#skip(long) 2816 * @since 2.0 2817 */ 2818 public static void skipFully(final Reader reader, final long toSkip) throws IOException { 2819 final long skipped = skip(reader, toSkip); 2820 if (skipped != toSkip) { 2821 throw new EOFException("Chars to skip: " + toSkip + " actual: " + skipped); 2822 } 2823 } 2824 2825 /** 2826 * Fetches entire contents of an {@link InputStream} and represent same data as result InputStream. 2827 * <p> 2828 * This method is useful where, 2829 * </p> 2830 * <ul> 2831 * <li>Source InputStream is slow.</li> 2832 * <li>It has network resources associated, so we cannot keep it open for long time.</li> 2833 * <li>It has network timeout associated.</li> 2834 * </ul> 2835 * <p> 2836 * It can be used in favor of {@link #toByteArray(InputStream)}, since it avoids unnecessary allocation and copy of byte[].<br> 2837 * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. 2838 * </p> 2839 * 2840 * @param input Stream to be fully buffered. 2841 * @return A fully buffered stream. 2842 * @throws IOException if an I/O error occurs. 2843 * @since 2.0 2844 */ 2845 public static InputStream toBufferedInputStream(final InputStream input) throws IOException { 2846 return ByteArrayOutputStream.toBufferedInputStream(input); 2847 } 2848 2849 /** 2850 * Fetches entire contents of an {@link InputStream} and represent same data as result InputStream. 2851 * <p> 2852 * This method is useful where, 2853 * </p> 2854 * <ul> 2855 * <li>Source InputStream is slow.</li> 2856 * <li>It has network resources associated, so we cannot keep it open for long time.</li> 2857 * <li>It has network timeout associated.</li> 2858 * </ul> 2859 * <p> 2860 * It can be used in favor of {@link #toByteArray(InputStream)}, since it avoids unnecessary allocation and copy of byte[].<br> 2861 * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. 2862 * </p> 2863 * 2864 * @param input Stream to be fully buffered. 2865 * @param size the initial buffer size. 2866 * @return A fully buffered stream. 2867 * @throws IOException if an I/O error occurs. 2868 * @since 2.5 2869 */ 2870 public static InputStream toBufferedInputStream(final InputStream input, final int size) throws IOException { 2871 return ByteArrayOutputStream.toBufferedInputStream(input, size); 2872 } 2873 2874 /** 2875 * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given 2876 * reader. 2877 * 2878 * @param reader the reader to wrap or return (not null). 2879 * @return the given reader or a new {@link BufferedReader} for the given reader. 2880 * @throws NullPointerException if the input parameter is null. 2881 * @see #buffer(Reader) 2882 * @since 2.2 2883 */ 2884 public static BufferedReader toBufferedReader(final Reader reader) { 2885 return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader); 2886 } 2887 2888 /** 2889 * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given 2890 * reader. 2891 * 2892 * @param reader the reader to wrap or return (not null). 2893 * @param size the buffer size, if a new BufferedReader is created. 2894 * @return the given reader or a new {@link BufferedReader} for the given reader. 2895 * @throws NullPointerException if the input parameter is null. 2896 * @see #buffer(Reader) 2897 * @since 2.5 2898 */ 2899 public static BufferedReader toBufferedReader(final Reader reader, final int size) { 2900 return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader, size); 2901 } 2902 2903 /** 2904 * Reads all the bytes from an input stream in a byte array. 2905 * 2906 * <p>The memory used by this method is <strong>proportional</strong> to the number 2907 * of bytes read, which is only limited by {@link Integer#MAX_VALUE}. Only streams 2908 * which fit into a single byte array with roughly 2 GiB limit can be processed 2909 * with this method.</p> 2910 * 2911 * @param inputStream The {@link InputStream} to read; must not be {@code null}. 2912 * @return A new byte array. 2913 * @throws IOException If an I/O error occurs while reading or if the maximum array size is exceeded. 2914 * @throws NullPointerException If {@code inputStream} is {@code null}. 2915 */ 2916 public static byte[] toByteArray(final InputStream inputStream) throws IOException { 2917 // Using SOFT_MAX_ARRAY_LENGTH guarantees that size() will not overflow 2918 final UnsynchronizedByteArrayOutputStream output = copyToOutputStream(inputStream, SOFT_MAX_ARRAY_LENGTH + 1, DEFAULT_BUFFER_SIZE); 2919 if (output.size() > SOFT_MAX_ARRAY_LENGTH) { 2920 throw new IOException(String.format("Cannot read more than %,d into a byte array", SOFT_MAX_ARRAY_LENGTH)); 2921 } 2922 return output.toByteArray(); 2923 } 2924 2925 /** 2926 * Reads exactly {@code size} bytes from the given {@link InputStream} into a new {@code byte[]}. 2927 * 2928 * <p>This variant always allocates the whole requested array size, 2929 * for a dynamic growing variant use {@link #toByteArray(InputStream, int, int)}, 2930 * which enforces stricter memory usage constraints.</p> 2931 * 2932 * @param input the {@link InputStream} to read; must not be {@code null}. 2933 * @param size the exact number of bytes to read; must be {@code >= 0}. 2934 * @return a new byte array of length {@code size}. 2935 * @throws IllegalArgumentException if {@code size} is negative. 2936 * @throws EOFException if the stream ends before {@code size} bytes are read. 2937 * @throws IOException if an I/O error occurs while reading. 2938 * @throws NullPointerException if {@code input} is {@code null}. 2939 * @since 2.1 2940 */ 2941 public static byte[] toByteArray(final InputStream input, final int size) throws IOException { 2942 return toByteArray(Objects.requireNonNull(input, "input")::read, size); 2943 } 2944 2945 /** 2946 * Reads exactly {@code size} bytes from the given {@link InputStream} into a new {@code byte[]}. 2947 * 2948 * <p>The memory used by this method is <strong>proportional</strong> to the number 2949 * of bytes read and limited by the specified {@code size}. This makes it suitable for 2950 * processing large input streams, provided that <strong>sufficient</strong> heap space is 2951 * available.</p> 2952 * 2953 * <p>This method processes the input stream in successive chunks of up to 2954 * {@code chunkSize} bytes.</p> 2955 * 2956 * @param input the {@link InputStream} to read; must not be {@code null}. 2957 * @param size the exact number of bytes to read; must be {@code >= 0}. 2958 * The actual bytes read are validated to equal {@code size}. 2959 * @param chunkSize The chunk size for incremental reading; must be {@code > 0}. 2960 * @return a new byte array of length {@code size}. 2961 * @throws IllegalArgumentException if {@code size} is negative or {@code chunkSize <= 0}. 2962 * @throws EOFException if the stream ends before {@code size} bytes are read. 2963 * @throws IOException if an I/O error occurs while reading. 2964 * @throws NullPointerException if {@code input} is {@code null}. 2965 * @since 2.21.0 2966 */ 2967 public static byte[] toByteArray(final InputStream input, final int size, final int chunkSize) throws IOException { 2968 Objects.requireNonNull(input, "input"); 2969 if (chunkSize <= 0) { 2970 throw new IllegalArgumentException(String.format("chunkSize <= 0, chunkSize = %,d", chunkSize)); 2971 } 2972 if (size <= chunkSize) { 2973 // throws if size < 0 2974 return toByteArray(input::read, size); 2975 } 2976 final UnsynchronizedByteArrayOutputStream output = copyToOutputStream(input, size, chunkSize); 2977 final int outSize = output.size(); 2978 if (outSize != size) { 2979 throw new EOFException(String.format("Expected read size: %,d, actual: %,d", size, outSize)); 2980 } 2981 return output.toByteArray(); 2982 } 2983 2984 /** 2985 * Reads exactly {@code size} bytes from the given {@link InputStream} into a new {@code byte[]}. 2986 * 2987 * <p>This variant always allocates the whole requested array size, 2988 * for a dynamic growing variant use {@link #toByteArray(InputStream, int, int)}, 2989 * which enforces stricter memory usage constraints.</p> 2990 * 2991 * @param input the {@link InputStream} to read; must not be {@code null}. 2992 * @param size the exact number of bytes to read; must be {@code >= 0} and {@code <= Integer.MAX_VALUE}. 2993 * @return a new byte array of length {@code size}. 2994 * @throws IllegalArgumentException if {@code size} is negative or does not fit into an int. 2995 * @throws EOFException if the stream ends before {@code size} bytes are read. 2996 * @throws IOException if an I/O error occurs while reading. 2997 * @throws NullPointerException if {@code input} is {@code null}. 2998 * @see #toByteArray(InputStream, int, int) 2999 * @since 2.1 3000 */ 3001 public static byte[] toByteArray(final InputStream input, final long size) throws IOException { 3002 if (size > Integer.MAX_VALUE) { 3003 throw new IllegalArgumentException(String.format("size > Integer.MAX_VALUE, size = %,d", size)); 3004 } 3005 return toByteArray(input, (int) size); 3006 } 3007 3008 /** 3009 * Gets the contents of an input as a {@code byte[]}. 3010 * 3011 * @param input the input to read, not null. 3012 * @param size the size of the input to read, where 0 < {@code size} <= length of input. 3013 * @return byte [] of length {@code size}. 3014 * @throws EOFException if the end of the input is reached before reading {@code size} bytes. 3015 * @throws IOException if an I/O error occurs or input length is smaller than parameter {@code size}. 3016 * @throws IllegalArgumentException if {@code size} is less than zero. 3017 */ 3018 static byte[] toByteArray(final IOTriFunction<byte[], Integer, Integer, Integer> input, final int size) throws IOException { 3019 if (size < 0) { 3020 throw new IllegalArgumentException(String.format("size < 0, size = %,d", size)); 3021 } 3022 if (size == 0) { 3023 return EMPTY_BYTE_ARRAY; 3024 } 3025 final byte[] data = byteArray(size); 3026 int offset = 0; 3027 int read; 3028 while (offset < size && (read = input.apply(data, offset, size - offset)) != EOF) { 3029 offset += read; 3030 } 3031 if (offset != size) { 3032 throw new EOFException(String.format("Expected read size: %,d, actual: %,d", size, offset)); 3033 } 3034 return data; 3035 } 3036 3037 /** 3038 * Gets the contents of a {@link Reader} as a {@code byte[]} 3039 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. 3040 * <p> 3041 * This method buffers the input internally, so there is no need to use a 3042 * {@link BufferedReader}. 3043 * </p> 3044 * 3045 * @param reader the {@link Reader} to read. 3046 * @return the requested byte array. 3047 * @throws NullPointerException if the input is null. 3048 * @throws IOException if an I/O error occurs. 3049 * @deprecated Use {@link #toByteArray(Reader, Charset)} instead. 3050 */ 3051 @Deprecated 3052 public static byte[] toByteArray(final Reader reader) throws IOException { 3053 return toByteArray(reader, Charset.defaultCharset()); 3054 } 3055 3056 /** 3057 * Gets the contents of a {@link Reader} as a {@code byte[]} 3058 * using the specified character encoding. 3059 * <p> 3060 * This method buffers the input internally, so there is no need to use a 3061 * {@link BufferedReader}. 3062 * </p> 3063 * 3064 * @param reader the {@link Reader} to read. 3065 * @param charset the charset to use, null means platform default. 3066 * @return the requested byte array. 3067 * @throws NullPointerException if the input is null. 3068 * @throws IOException if an I/O error occurs. 3069 * @since 2.3 3070 */ 3071 public static byte[] toByteArray(final Reader reader, final Charset charset) throws IOException { 3072 try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { 3073 copy(reader, output, charset); 3074 return output.toByteArray(); 3075 } 3076 } 3077 3078 /** 3079 * Gets the contents of a {@link Reader} as a {@code byte[]} 3080 * using the specified character encoding. 3081 * <p> 3082 * Character encoding names can be found at 3083 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 3084 * </p> 3085 * <p> 3086 * This method buffers the input internally, so there is no need to use a 3087 * {@link BufferedReader}. 3088 * </p> 3089 * 3090 * @param reader the {@link Reader} to read. 3091 * @param charsetName the name of the requested charset, null means platform default. 3092 * @return the requested byte array. 3093 * @throws NullPointerException if the input is null. 3094 * @throws IOException if an I/O error occurs. 3095 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 3096 * @since 1.1 3097 */ 3098 public static byte[] toByteArray(final Reader reader, final String charsetName) throws IOException { 3099 return toByteArray(reader, Charsets.toCharset(charsetName)); 3100 } 3101 3102 /** 3103 * Gets the contents of a {@link String} as a {@code byte[]} 3104 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. 3105 * <p> 3106 * This is the same as {@link String#getBytes()}. 3107 * </p> 3108 * 3109 * @param input the {@link String} to convert. 3110 * @return the requested byte array. 3111 * @throws NullPointerException if the input is null. 3112 * @deprecated Use {@link String#getBytes()} instead. 3113 */ 3114 @Deprecated 3115 public static byte[] toByteArray(final String input) { 3116 // make explicit the use of the default charset 3117 return input.getBytes(Charset.defaultCharset()); 3118 } 3119 3120 /** 3121 * Gets the contents of a {@link URI} as a {@code byte[]}. 3122 * 3123 * @param uri the {@link URI} to read. 3124 * @return the requested byte array. 3125 * @throws NullPointerException if the uri is null. 3126 * @throws IOException if an I/O exception occurs. 3127 * @since 2.4 3128 */ 3129 public static byte[] toByteArray(final URI uri) throws IOException { 3130 return toByteArray(uri.toURL()); 3131 } 3132 3133 /** 3134 * Gets the contents of a {@link URL} as a {@code byte[]}. 3135 * 3136 * @param url the {@link URL} to read. 3137 * @return the requested byte array. 3138 * @throws NullPointerException if the input is null. 3139 * @throws IOException if an I/O exception occurs. 3140 * @since 2.4 3141 */ 3142 public static byte[] toByteArray(final URL url) throws IOException { 3143 try (CloseableURLConnection urlConnection = CloseableURLConnection.open(url)) { 3144 return toByteArray(urlConnection); 3145 } 3146 } 3147 3148 /** 3149 * Gets the contents of a {@link URLConnection} as a {@code byte[]}. 3150 * 3151 * @param urlConnection the {@link URLConnection} to read. 3152 * @return the requested byte array. 3153 * @throws NullPointerException if the urlConn is null. 3154 * @throws IOException if an I/O exception occurs. 3155 * @since 2.4 3156 */ 3157 public static byte[] toByteArray(final URLConnection urlConnection) throws IOException { 3158 try (InputStream inputStream = urlConnection.getInputStream()) { 3159 return toByteArray(inputStream); 3160 } 3161 } 3162 3163 /** 3164 * Gets the contents of an {@link InputStream} as a character array 3165 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. 3166 * <p> 3167 * This method buffers the input internally, so there is no need to use a 3168 * {@link BufferedInputStream}. 3169 * </p> 3170 * 3171 * @param inputStream the {@link InputStream} to read. 3172 * @return the requested character array. 3173 * @throws NullPointerException if the input is null. 3174 * @throws IOException if an I/O error occurs. 3175 * @since 1.1 3176 * @deprecated Use {@link #toCharArray(InputStream, Charset)} instead 3177 */ 3178 @Deprecated 3179 public static char[] toCharArray(final InputStream inputStream) throws IOException { 3180 return toCharArray(inputStream, Charset.defaultCharset()); 3181 } 3182 3183 /** 3184 * Gets the contents of an {@link InputStream} as a character array 3185 * using the specified character encoding. 3186 * <p> 3187 * This method buffers the input internally, so there is no need to use a 3188 * {@link BufferedInputStream}. 3189 * </p> 3190 * 3191 * @param inputStream the {@link InputStream} to read. 3192 * @param charset the charset to use, null means platform default. 3193 * @return the requested character array. 3194 * @throws NullPointerException if the input is null. 3195 * @throws IOException if an I/O error occurs. 3196 * @since 2.3 3197 */ 3198 public static char[] toCharArray(final InputStream inputStream, final Charset charset) 3199 throws IOException { 3200 final CharArrayWriter writer = new CharArrayWriter(); 3201 copy(inputStream, writer, charset); 3202 return writer.toCharArray(); 3203 } 3204 3205 /** 3206 * Gets the contents of an {@link InputStream} as a character array 3207 * using the specified character encoding. 3208 * <p> 3209 * Character encoding names can be found at 3210 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 3211 * </p> 3212 * <p> 3213 * This method buffers the input internally, so there is no need to use a 3214 * {@link BufferedInputStream}. 3215 * </p> 3216 * 3217 * @param inputStream the {@link InputStream} to read. 3218 * @param charsetName the name of the requested charset, null means platform default. 3219 * @return the requested character array. 3220 * @throws NullPointerException if the input is null. 3221 * @throws IOException if an I/O error occurs. 3222 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 3223 * @since 1.1 3224 */ 3225 public static char[] toCharArray(final InputStream inputStream, final String charsetName) throws IOException { 3226 return toCharArray(inputStream, Charsets.toCharset(charsetName)); 3227 } 3228 3229 /** 3230 * Gets the contents of a {@link Reader} as a character array. 3231 * <p> 3232 * This method buffers the input internally, so there is no need to use a 3233 * {@link BufferedReader}. 3234 * </p> 3235 * 3236 * @param reader the {@link Reader} to read. 3237 * @return the requested character array. 3238 * @throws NullPointerException if the input is null. 3239 * @throws IOException if an I/O error occurs. 3240 * @since 1.1 3241 */ 3242 public static char[] toCharArray(final Reader reader) throws IOException { 3243 final CharArrayWriter sw = new CharArrayWriter(); 3244 copy(reader, sw); 3245 return sw.toCharArray(); 3246 } 3247 3248 /** 3249 * Converts the specified CharSequence to an input stream, encoded as bytes 3250 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. 3251 * 3252 * @param input the CharSequence to convert. 3253 * @return an input stream. 3254 * @since 2.0 3255 * @deprecated Use {@link #toInputStream(CharSequence, Charset)} instead. 3256 */ 3257 @Deprecated 3258 public static InputStream toInputStream(final CharSequence input) { 3259 return toInputStream(input, Charset.defaultCharset()); 3260 } 3261 3262 /** 3263 * Converts the specified CharSequence to an input stream, encoded as bytes 3264 * using the specified character encoding. 3265 * 3266 * @param input the CharSequence to convert. 3267 * @param charset the charset to use, null means platform default. 3268 * @return an input stream. 3269 * @since 2.3 3270 */ 3271 public static InputStream toInputStream(final CharSequence input, final Charset charset) { 3272 return toInputStream(input.toString(), charset); 3273 } 3274 3275 /** 3276 * Converts the specified CharSequence to an input stream, encoded as bytes 3277 * using the specified character encoding. 3278 * <p> 3279 * Character encoding names can be found at 3280 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 3281 * </p> 3282 * 3283 * @param input the CharSequence to convert. 3284 * @param charsetName the name of the requested charset, null means platform default. 3285 * @return an input stream. 3286 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 3287 * @since 2.0 3288 */ 3289 public static InputStream toInputStream(final CharSequence input, final String charsetName) { 3290 return toInputStream(input, Charsets.toCharset(charsetName)); 3291 } 3292 3293 /** 3294 * Converts the specified string to an input stream, encoded as bytes 3295 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. 3296 * 3297 * @param input the string to convert. 3298 * @return an input stream. 3299 * @since 1.1 3300 * @deprecated Use {@link #toInputStream(String, Charset)} instead. 3301 */ 3302 @Deprecated 3303 public static InputStream toInputStream(final String input) { 3304 return toInputStream(input, Charset.defaultCharset()); 3305 } 3306 3307 /** 3308 * Converts the specified string to an input stream, encoded as bytes 3309 * using the specified character encoding. 3310 * 3311 * @param input the string to convert. 3312 * @param charset the charset to use, null means platform default. 3313 * @return an input stream. 3314 * @since 2.3 3315 */ 3316 public static InputStream toInputStream(final String input, final Charset charset) { 3317 return new ByteArrayInputStream(input.getBytes(Charsets.toCharset(charset))); 3318 } 3319 3320 /** 3321 * Converts the specified string to an input stream, encoded as bytes 3322 * using the specified character encoding. 3323 * <p> 3324 * Character encoding names can be found at 3325 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 3326 * </p> 3327 * 3328 * @param input the string to convert. 3329 * @param charsetName the name of the requested charset, null means platform default. 3330 * @return an input stream. 3331 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 3332 * @since 1.1 3333 */ 3334 public static InputStream toInputStream(final String input, final String charsetName) { 3335 return new ByteArrayInputStream(input.getBytes(Charsets.toCharset(charsetName))); 3336 } 3337 3338 /** 3339 * Gets the contents of a {@code byte[]} as a String 3340 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. 3341 * 3342 * @param input the byte array to read. 3343 * @return the requested String. 3344 * @throws NullPointerException if the input is null. 3345 * @deprecated Use {@link String#String(byte[])} instead. 3346 */ 3347 @Deprecated 3348 public static String toString(final byte[] input) { 3349 // make explicit the use of the default charset 3350 return new String(input, Charset.defaultCharset()); 3351 } 3352 3353 /** 3354 * Gets the contents of a {@code byte[]} as a String 3355 * using the specified character encoding. 3356 * <p> 3357 * Character encoding names can be found at 3358 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 3359 * </p> 3360 * 3361 * @param input the byte array to read. 3362 * @param charsetName the name of the requested charset, null means platform default. 3363 * @return the requested String. 3364 * @throws NullPointerException if the input is null. 3365 */ 3366 public static String toString(final byte[] input, final String charsetName) { 3367 return new String(input, Charsets.toCharset(charsetName)); 3368 } 3369 3370 /** 3371 * Gets the contents of an {@link InputStream} as a String 3372 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. 3373 * <p> 3374 * This method buffers the input internally, so there is no need to use a 3375 * {@link BufferedInputStream}. 3376 * </p> 3377 * 3378 * @param input the {@link InputStream} to read. 3379 * @return the requested String. 3380 * @throws NullPointerException if the input is null. 3381 * @throws IOException if an I/O error occurs. 3382 * @deprecated Use {@link #toString(InputStream, Charset)} instead. 3383 */ 3384 @Deprecated 3385 public static String toString(final InputStream input) throws IOException { 3386 return toString(input, Charset.defaultCharset()); 3387 } 3388 3389 /** 3390 * Gets the contents of an {@link InputStream} as a String 3391 * using the specified character encoding. 3392 * <p> 3393 * This method buffers the input internally, so there is no need to use a 3394 * {@link BufferedInputStream}. 3395 * </p> 3396 * 3397 * @param input the {@link InputStream} to read. 3398 * @param charset the charset to use, null means platform default. 3399 * @return the requested String. 3400 * @throws NullPointerException if the input is null. 3401 * @throws IOException if an I/O error occurs. 3402 * @since 2.3 3403 */ 3404 public static String toString(final InputStream input, final Charset charset) throws IOException { 3405 try (StringBuilderWriter sw = new StringBuilderWriter()) { 3406 copy(input, sw, charset); 3407 return sw.toString(); 3408 } 3409 } 3410 3411 /** 3412 * Gets the contents of an {@link InputStream} as a String 3413 * using the specified character encoding. 3414 * <p> 3415 * Character encoding names can be found at 3416 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 3417 * </p> 3418 * <p> 3419 * This method buffers the input internally, so there is no need to use a 3420 * {@link BufferedInputStream}. 3421 * </p> 3422 * 3423 * @param input the {@link InputStream} to read. 3424 * @param charsetName the name of the requested charset, null means platform default. 3425 * @return the requested String. 3426 * @throws NullPointerException if the input is null. 3427 * @throws IOException if an I/O error occurs. 3428 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 3429 */ 3430 public static String toString(final InputStream input, final String charsetName) 3431 throws IOException { 3432 return toString(input, Charsets.toCharset(charsetName)); 3433 } 3434 3435 /** 3436 * Gets the contents of an {@link InputStream} from a supplier as a String 3437 * using the specified character encoding. 3438 * <p> 3439 * This method buffers the input internally, so there is no need to use a 3440 * {@link BufferedInputStream}. 3441 * </p> 3442 * 3443 * @param input supplies the {@link InputStream} to read. 3444 * @param charset the charset to use, null means platform default. 3445 * @return the requested String. 3446 * @throws NullPointerException if the input is null. 3447 * @throws IOException if an I/O error occurs. 3448 * @since 2.12.0 3449 */ 3450 public static String toString(final IOSupplier<InputStream> input, final Charset charset) throws IOException { 3451 return toString(input, charset, () -> { 3452 throw new NullPointerException("input"); 3453 }); 3454 } 3455 3456 /** 3457 * Gets the contents of an {@link InputStream} from a supplier as a String 3458 * using the specified character encoding. 3459 * <p> 3460 * This method buffers the input internally, so there is no need to use a 3461 * {@link BufferedInputStream}. 3462 * </p> 3463 * 3464 * @param input supplies the {@link InputStream} to read. 3465 * @param charset the charset to use, null means platform default. 3466 * @param defaultString the default return value if the supplier or its value is null. 3467 * @return the requested String. 3468 * @throws NullPointerException if the input is null. 3469 * @throws IOException if an I/O error occurs. 3470 * @since 2.12.0 3471 */ 3472 public static String toString(final IOSupplier<InputStream> input, final Charset charset, final IOSupplier<String> defaultString) throws IOException { 3473 if (input == null) { 3474 return defaultString.get(); 3475 } 3476 try (InputStream inputStream = input.get()) { 3477 return inputStream != null ? toString(inputStream, charset) : defaultString.get(); 3478 } 3479 } 3480 3481 /** 3482 * Gets the contents of a {@link Reader} as a String. 3483 * <p> 3484 * This method buffers the input internally, so there is no need to use a 3485 * {@link BufferedReader}. 3486 * </p> 3487 * 3488 * @param reader the {@link Reader} to read. 3489 * @return the requested String. 3490 * @throws NullPointerException if the input is null. 3491 * @throws IOException if an I/O error occurs. 3492 */ 3493 public static String toString(final Reader reader) throws IOException { 3494 try (StringBuilderWriter sw = new StringBuilderWriter()) { 3495 copy(reader, sw); 3496 return sw.toString(); 3497 } 3498 } 3499 3500 /** 3501 * Gets the contents at the given URI using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. 3502 * 3503 * @param uri The URI source. 3504 * @return The contents of the URL as a String. 3505 * @throws IOException if an I/O exception occurs. 3506 * @since 2.1 3507 * @deprecated Use {@link #toString(URI, Charset)} instead. 3508 */ 3509 @Deprecated 3510 public static String toString(final URI uri) throws IOException { 3511 return toString(uri, Charset.defaultCharset()); 3512 } 3513 3514 /** 3515 * Gets the contents at the given URI. 3516 * 3517 * @param uri The URI source. 3518 * @param encoding The encoding name for the URL contents. 3519 * @return The contents of the URL as a String. 3520 * @throws IOException if an I/O exception occurs. 3521 * @since 2.3. 3522 */ 3523 public static String toString(final URI uri, final Charset encoding) throws IOException { 3524 return toString(uri.toURL(), Charsets.toCharset(encoding)); 3525 } 3526 3527 /** 3528 * Gets the contents at the given URI. 3529 * 3530 * @param uri The URI source. 3531 * @param charsetName The encoding name for the URL contents. 3532 * @return The contents of the URL as a String. 3533 * @throws IOException if an I/O exception occurs. 3534 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 3535 * @since 2.1 3536 */ 3537 public static String toString(final URI uri, final String charsetName) throws IOException { 3538 return toString(uri, Charsets.toCharset(charsetName)); 3539 } 3540 3541 /** 3542 * Gets the contents at the given URL using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. 3543 * 3544 * @param url The URL source. 3545 * @return The contents of the URL as a String. 3546 * @throws IOException if an I/O exception occurs. 3547 * @since 2.1 3548 * @deprecated Use {@link #toString(URL, Charset)} instead. 3549 */ 3550 @Deprecated 3551 public static String toString(final URL url) throws IOException { 3552 return toString(url, Charset.defaultCharset()); 3553 } 3554 3555 /** 3556 * Gets the contents at the given URL. 3557 * 3558 * @param url The URL source. 3559 * @param encoding The encoding name for the URL contents. 3560 * @return The contents of the URL as a String. 3561 * @throws IOException if an I/O exception occurs. 3562 * @since 2.3 3563 */ 3564 public static String toString(final URL url, final Charset encoding) throws IOException { 3565 return toString(url::openStream, encoding); 3566 } 3567 3568 /** 3569 * Gets the contents at the given URL. 3570 * 3571 * @param url The URL source. 3572 * @param charsetName The encoding name for the URL contents. 3573 * @return The contents of the URL as a String. 3574 * @throws IOException if an I/O exception occurs. 3575 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 3576 * @since 2.1 3577 */ 3578 public static String toString(final URL url, final String charsetName) throws IOException { 3579 return toString(url, Charsets.toCharset(charsetName)); 3580 } 3581 3582 /** 3583 * Writes bytes from a {@code byte[]} to an {@link OutputStream}. 3584 * 3585 * @param data the byte array to write, do not modify during output, null ignored. 3586 * @param output the {@link OutputStream} to write to. 3587 * @throws NullPointerException if output is null. 3588 * @throws IOException if an I/O error occurs. 3589 * @since 1.1 3590 */ 3591 public static void write(final byte[] data, final OutputStream output) 3592 throws IOException { 3593 if (data != null) { 3594 output.write(data); 3595 } 3596 } 3597 3598 /** 3599 * Writes bytes from a {@code byte[]} to chars on a {@link Writer} 3600 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. 3601 * <p> 3602 * This method uses {@link String#String(byte[])}. 3603 * </p> 3604 * 3605 * @param data the byte array to write, do not modify during output, 3606 * null ignored 3607 * @param writer the {@link Writer} to write to. 3608 * @throws NullPointerException if output is null. 3609 * @throws IOException if an I/O error occurs. 3610 * @since 1.1 3611 * @deprecated Use {@link #write(byte[], Writer, Charset)} instead. 3612 */ 3613 @Deprecated 3614 public static void write(final byte[] data, final Writer writer) throws IOException { 3615 write(data, writer, Charset.defaultCharset()); 3616 } 3617 3618 /** 3619 * Writes bytes from a {@code byte[]} to chars on a {@link Writer} 3620 * using the specified character encoding. 3621 * <p> 3622 * This method uses {@link String#String(byte[], String)}. 3623 * </p> 3624 * 3625 * @param data the byte array to write, do not modify during output, 3626 * null ignored 3627 * @param writer the {@link Writer} to write to. 3628 * @param charset the charset to use, null means platform default. 3629 * @throws NullPointerException if output is null. 3630 * @throws IOException if an I/O error occurs. 3631 * @since 2.3 3632 */ 3633 public static void write(final byte[] data, final Writer writer, final Charset charset) throws IOException { 3634 if (data != null) { 3635 writer.write(new String(data, Charsets.toCharset(charset))); 3636 } 3637 } 3638 3639 /** 3640 * Writes bytes from a {@code byte[]} to chars on a {@link Writer} using the specified character encoding. 3641 * <p> 3642 * Character encoding names can be found at <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 3643 * </p> 3644 * <p> 3645 * This method uses {@link String#String(byte[], String)}. 3646 * </p> 3647 * 3648 * @param data the byte array to write, do not modify during output, null ignored. 3649 * @param writer the {@link Writer} to write to. 3650 * @param charsetName the name of the requested charset, null means platform default. 3651 * @throws NullPointerException if output is null. 3652 * @throws IOException if an I/O error occurs. 3653 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 3654 * @since 1.1 3655 */ 3656 public static void write(final byte[] data, final Writer writer, final String charsetName) throws IOException { 3657 write(data, writer, Charsets.toCharset(charsetName)); 3658 } 3659 3660 /** 3661 * Writes chars from a {@code char[]} to bytes on an {@link OutputStream}. 3662 * <p> 3663 * This method uses the virtual machine's {@linkplain Charset#defaultCharset() default charset}. 3664 * </p> 3665 * 3666 * @param data the char array to write, do not modify during output, null ignored. 3667 * @param output the {@link OutputStream} to write to. 3668 * @throws NullPointerException if output is null. 3669 * @throws IOException if an I/O error occurs. 3670 * @since 1.1 3671 * @deprecated Use {@link #write(char[], OutputStream, Charset)} instead. 3672 */ 3673 @Deprecated 3674 public static void write(final char[] data, final OutputStream output) 3675 throws IOException { 3676 write(data, output, Charset.defaultCharset()); 3677 } 3678 3679 /** 3680 * Writes chars from a {@code char[]} to bytes on an {@link OutputStream} using the specified character encoding. 3681 * <p> 3682 * This method uses {@link String#String(char[])} and {@link String#getBytes(String)}. 3683 * </p> 3684 * 3685 * @param data the char array to write, do not modify during output, null ignored. 3686 * @param output the {@link OutputStream} to write to. 3687 * @param charset the charset to use, null means platform default. 3688 * @throws NullPointerException if output is null. 3689 * @throws IOException if an I/O error occurs. 3690 * @since 2.3 3691 */ 3692 public static void write(final char[] data, final OutputStream output, final Charset charset) throws IOException { 3693 if (data != null) { 3694 write(new String(data), output, charset); 3695 } 3696 } 3697 3698 /** 3699 * Writes chars from a {@code char[]} to bytes on an {@link OutputStream} using the specified character encoding. 3700 * <p> 3701 * Character encoding names can be found at <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 3702 * </p> 3703 * <p> 3704 * This method uses {@link String#String(char[])} and {@link String#getBytes(String)}. 3705 * </p> 3706 * 3707 * @param data the char array to write, do not modify during output, null ignored. 3708 * @param output the {@link OutputStream} to write to. 3709 * @param charsetName the name of the requested charset, null means platform default. 3710 * @throws NullPointerException if output is null. 3711 * @throws IOException if an I/O error occurs. 3712 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 3713 * @since 1.1 3714 */ 3715 public static void write(final char[] data, final OutputStream output, final String charsetName) 3716 throws IOException { 3717 write(data, output, Charsets.toCharset(charsetName)); 3718 } 3719 3720 /** 3721 * Writes chars from a {@code char[]} to a {@link Writer} 3722 * 3723 * @param data the char array to write, do not modify during output, null ignored. 3724 * @param writer the {@link Writer} to write to. 3725 * @throws NullPointerException if output is null. 3726 * @throws IOException if an I/O error occurs. 3727 * @since 1.1 3728 */ 3729 public static void write(final char[] data, final Writer writer) throws IOException { 3730 if (data != null) { 3731 writer.write(data); 3732 } 3733 } 3734 3735 /** 3736 * Writes chars from a {@link CharSequence} to bytes on an {@link OutputStream} using the virtual machine's {@link Charset#defaultCharset() default 3737 * charset}. 3738 * <p> 3739 * This method uses {@link String#getBytes()}. 3740 * </p> 3741 * 3742 * @param data the {@link CharSequence} to write, null ignored. 3743 * @param output the {@link OutputStream} to write to. 3744 * @throws NullPointerException if output is null. 3745 * @throws IOException if an I/O error occurs. 3746 * @since 2.0 3747 * @deprecated Use {@link #write(CharSequence, OutputStream, Charset)} instead. 3748 */ 3749 @Deprecated 3750 public static void write(final CharSequence data, final OutputStream output) 3751 throws IOException { 3752 write(data, output, Charset.defaultCharset()); 3753 } 3754 3755 /** 3756 * Writes chars from a {@link CharSequence} to bytes on an {@link OutputStream} using the specified character encoding. 3757 * <p> 3758 * This method uses {@link String#getBytes(String)}. 3759 * </p> 3760 * 3761 * @param data the {@link CharSequence} to write, null ignored. 3762 * @param output the {@link OutputStream} to write to. 3763 * @param charset the charset to use, null means platform default. 3764 * @throws NullPointerException if output is null. 3765 * @throws IOException if an I/O error occurs. 3766 * @since 2.3 3767 */ 3768 public static void write(final CharSequence data, final OutputStream output, final Charset charset) 3769 throws IOException { 3770 if (data != null) { 3771 write(data.toString(), output, charset); 3772 } 3773 } 3774 3775 /** 3776 * Writes chars from a {@link CharSequence} to bytes on an {@link OutputStream} using the specified character encoding. 3777 * <p> 3778 * Character encoding names can be found at <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 3779 * </p> 3780 * <p> 3781 * This method uses {@link String#getBytes(String)}. 3782 * </p> 3783 * 3784 * @param data the {@link CharSequence} to write, null ignored. 3785 * @param output the {@link OutputStream} to write to. 3786 * @param charsetName the name of the requested charset, null means platform default. 3787 * @throws NullPointerException if output is null. 3788 * @throws IOException if an I/O error occurs. 3789 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 3790 * @since 2.0 3791 */ 3792 public static void write(final CharSequence data, final OutputStream output, final String charsetName) 3793 throws IOException { 3794 write(data, output, Charsets.toCharset(charsetName)); 3795 } 3796 3797 /** 3798 * Writes chars from a {@link CharSequence} to a {@link Writer}. 3799 * 3800 * @param data the {@link CharSequence} to write, null ignored. 3801 * @param writer the {@link Writer} to write to. 3802 * @throws NullPointerException if output is null. 3803 * @throws IOException if an I/O error occurs. 3804 * @since 2.0 3805 */ 3806 public static void write(final CharSequence data, final Writer writer) throws IOException { 3807 if (data != null) { 3808 write(data.toString(), writer); 3809 } 3810 } 3811 3812 /** 3813 * Writes chars from a {@link String} to bytes on an 3814 * {@link OutputStream} using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. 3815 * <p> 3816 * This method uses {@link String#getBytes()}. 3817 * </p> 3818 * 3819 * @param data the {@link String} to write, null ignored. 3820 * @param output the {@link OutputStream} to write to. 3821 * @throws NullPointerException if output is null. 3822 * @throws IOException if an I/O error occurs. 3823 * @since 1.1 3824 * @deprecated Use {@link #write(String, OutputStream, Charset)} instead 3825 */ 3826 @Deprecated 3827 public static void write(final String data, final OutputStream output) 3828 throws IOException { 3829 write(data, output, Charset.defaultCharset()); 3830 } 3831 3832 /** 3833 * Writes chars from a {@link String} to bytes on an 3834 * {@link OutputStream} using the specified character encoding. 3835 * <p> 3836 * This method uses {@link String#getBytes(String)}. 3837 * </p> 3838 * 3839 * @param data the {@link String} to write, null ignored. 3840 * @param output the {@link OutputStream} to write to. 3841 * @param charset the charset to use, null means platform default. 3842 * @throws NullPointerException if output is null. 3843 * @throws IOException if an I/O error occurs. 3844 * @since 2.3 3845 */ 3846 @SuppressWarnings("resource") 3847 public static void write(final String data, final OutputStream output, final Charset charset) throws IOException { 3848 if (data != null) { 3849 // Use Charset#encode(String), since calling String#getBytes(Charset) might result in 3850 // NegativeArraySizeException or OutOfMemoryError. 3851 // The underlying OutputStream should not be closed, so the channel is not closed. 3852 Channels.newChannel(output).write(Charsets.toCharset(charset).encode(data)); 3853 } 3854 } 3855 3856 /** 3857 * Writes chars from a {@link String} to bytes on an 3858 * {@link OutputStream} using the specified character encoding. 3859 * <p> 3860 * Character encoding names can be found at 3861 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 3862 * </p> 3863 * <p> 3864 * This method uses {@link String#getBytes(String)}. 3865 * </p> 3866 * 3867 * @param data the {@link String} to write, null ignored. 3868 * @param output the {@link OutputStream} to write to. 3869 * @param charsetName the name of the requested charset, null means platform default. 3870 * @throws NullPointerException if output is null. 3871 * @throws IOException if an I/O error occurs. 3872 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 3873 * @since 1.1 3874 */ 3875 public static void write(final String data, final OutputStream output, final String charsetName) 3876 throws IOException { 3877 write(data, output, Charsets.toCharset(charsetName)); 3878 } 3879 3880 /** 3881 * Writes chars from a {@link String} to a {@link Writer}. 3882 * 3883 * @param data the {@link String} to write, null ignored. 3884 * @param writer the {@link Writer} to write to. 3885 * @throws NullPointerException if output is null. 3886 * @throws IOException if an I/O error occurs. 3887 * @since 1.1 3888 */ 3889 public static void write(final String data, final Writer writer) throws IOException { 3890 if (data != null) { 3891 writer.write(data); 3892 } 3893 } 3894 3895 /** 3896 * Writes chars from a {@link StringBuffer} to bytes on an 3897 * {@link OutputStream} using the default character encoding of the 3898 * platform. 3899 * <p> 3900 * This method uses {@link String#getBytes()}. 3901 * </p> 3902 * 3903 * @param data the {@link StringBuffer} to write, null ignored. 3904 * @param output the {@link OutputStream} to write to. 3905 * @throws NullPointerException if output is null. 3906 * @throws IOException if an I/O error occurs 3907 * @since 1.1 3908 * @deprecated Use {@link #write(CharSequence, OutputStream)}. 3909 */ 3910 @Deprecated 3911 public static void write(final StringBuffer data, final OutputStream output) //NOSONAR 3912 throws IOException { 3913 write(data, output, (String) null); 3914 } 3915 3916 /** 3917 * Writes chars from a {@link StringBuffer} to bytes on an 3918 * {@link OutputStream} using the specified character encoding. 3919 * <p> 3920 * Character encoding names can be found at 3921 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 3922 * </p> 3923 * <p> 3924 * This method uses {@link String#getBytes(String)}. 3925 * </p> 3926 * 3927 * @param data the {@link StringBuffer} to write, null ignored. 3928 * @param output the {@link OutputStream} to write to. 3929 * @param charsetName the name of the requested charset, null means platform default. 3930 * @throws NullPointerException if output is null. 3931 * @throws IOException if an I/O error occurs. 3932 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 3933 * @since 1.1 3934 * @deprecated Use {@link #write(CharSequence, OutputStream, String)}. 3935 */ 3936 @Deprecated 3937 public static void write(final StringBuffer data, final OutputStream output, final String charsetName) //NOSONAR 3938 throws IOException { 3939 if (data != null) { 3940 write(data.toString(), output, Charsets.toCharset(charsetName)); 3941 } 3942 } 3943 3944 /** 3945 * Writes chars from a {@link StringBuffer} to a {@link Writer}. 3946 * 3947 * @param data the {@link StringBuffer} to write, null ignored. 3948 * @param writer the {@link Writer} to write to. 3949 * @throws NullPointerException if output is null. 3950 * @throws IOException if an I/O error occurs. 3951 * @since 1.1 3952 * @deprecated Use {@link #write(CharSequence, Writer)}. 3953 */ 3954 @Deprecated 3955 public static void write(final StringBuffer data, final Writer writer) //NOSONAR 3956 throws IOException { 3957 if (data != null) { 3958 writer.write(data.toString()); 3959 } 3960 } 3961 3962 /** 3963 * Writes bytes from a {@code byte[]} to an {@link OutputStream} using chunked writes. 3964 * This is intended for writing very large byte arrays which might otherwise cause excessive 3965 * memory usage if the native code has to allocate a copy. 3966 * 3967 * @param data the byte array to write, do not modify during output, 3968 * null ignored. 3969 * @param output the {@link OutputStream} to write to. 3970 * @throws NullPointerException if output is null. 3971 * @throws IOException if an I/O error occurs. 3972 * @since 2.5 3973 */ 3974 public static void writeChunked(final byte[] data, final OutputStream output) 3975 throws IOException { 3976 if (data != null) { 3977 int bytes = data.length; 3978 int offset = 0; 3979 while (bytes > 0) { 3980 final int chunk = Math.min(bytes, DEFAULT_BUFFER_SIZE); 3981 output.write(data, offset, chunk); 3982 bytes -= chunk; 3983 offset += chunk; 3984 } 3985 } 3986 } 3987 3988 /** 3989 * Writes chars from a {@code char[]} to a {@link Writer} using chunked writes. This is intended for writing very large byte arrays which might otherwise 3990 * cause excessive memory usage if the native code has to allocate a copy. 3991 * 3992 * @param data the char array to write, do not modify during output, null ignored. 3993 * @param writer the {@link Writer} to write to. 3994 * @throws NullPointerException if output is null. 3995 * @throws IOException if an I/O error occurs. 3996 * @since 2.5 3997 */ 3998 public static void writeChunked(final char[] data, final Writer writer) throws IOException { 3999 if (data != null) { 4000 int bytes = data.length; 4001 int offset = 0; 4002 while (bytes > 0) { 4003 final int chunk = Math.min(bytes, DEFAULT_BUFFER_SIZE); 4004 writer.write(data, offset, chunk); 4005 bytes -= chunk; 4006 offset += chunk; 4007 } 4008 } 4009 } 4010 4011 /** 4012 * Writes the {@link #toString()} value of each item in a collection to an {@link OutputStream} line by line, using the virtual machine's 4013 * {@linkplain Charset#defaultCharset() default charset} and the specified line ending. 4014 * 4015 * @param lines the lines to write, null entries produce blank lines. 4016 * @param lineEnding the line separator to use, null is system default. 4017 * @param output the {@link OutputStream} to write to, not null, not closed. 4018 * @throws NullPointerException if the output is null. 4019 * @throws IOException if an I/O error occurs. 4020 * @since 1.1 4021 * @deprecated Use {@link #writeLines(Collection, String, OutputStream, Charset)} instead 4022 */ 4023 @Deprecated 4024 public static void writeLines(final Collection<?> lines, final String lineEnding, final OutputStream output) throws IOException { 4025 writeLines(lines, lineEnding, output, Charset.defaultCharset()); 4026 } 4027 4028 /** 4029 * Writes the {@link #toString()} value of each item in a collection to an {@link OutputStream} line by line, using the specified character encoding and the 4030 * specified line ending. 4031 * <p> 4032 * UTF-16 is written big-endian with no byte order mark. For little-endian, use UTF-16LE. For a BOM, write it to the stream before calling this method. 4033 * </p> 4034 * 4035 * @param lines the lines to write, null entries produce blank lines. 4036 * @param lineEnding the line separator to use, null is system default. 4037 * @param output the {@link OutputStream} to write to, not null, not closed. 4038 * @param charset the charset to use, null means platform default. 4039 * @throws NullPointerException if output is null. 4040 * @throws IOException if an I/O error occurs. 4041 * @since 2.3 4042 */ 4043 public static void writeLines(final Collection<?> lines, String lineEnding, final OutputStream output, Charset charset) throws IOException { 4044 if (lines == null) { 4045 return; 4046 } 4047 if (lineEnding == null) { 4048 lineEnding = System.lineSeparator(); 4049 } 4050 if (StandardCharsets.UTF_16.equals(charset)) { 4051 // don't write a BOM 4052 charset = StandardCharsets.UTF_16BE; 4053 } 4054 final byte[] eolBytes = lineEnding.getBytes(charset); 4055 for (final Object line : lines) { 4056 if (line != null) { 4057 write(line.toString(), output, charset); 4058 } 4059 output.write(eolBytes); 4060 } 4061 } 4062 4063 /** 4064 * Writes the {@link #toString()} value of each item in a collection to an {@link OutputStream} line by line, using the specified character encoding and the 4065 * specified line ending. 4066 * <p> 4067 * Character encoding names can be found at <a href="https://www.iana.org/assignments/character-sets">IANA</a>. 4068 * </p> 4069 * 4070 * @param lines the lines to write, null entries produce blank lines. 4071 * @param lineEnding the line separator to use, null is system default. 4072 * @param output the {@link OutputStream} to write to, not null, not closed. 4073 * @param charsetName the name of the requested charset, null means platform default. 4074 * @throws NullPointerException if the output is null. 4075 * @throws IOException if an I/O error occurs. 4076 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. 4077 * @since 1.1 4078 */ 4079 public static void writeLines(final Collection<?> lines, final String lineEnding, final OutputStream output, final String charsetName) throws IOException { 4080 writeLines(lines, lineEnding, output, Charsets.toCharset(charsetName)); 4081 } 4082 4083 /** 4084 * Writes the {@link #toString()} value of each item in a collection to a {@link Writer} line by line, using the specified line ending. 4085 * 4086 * @param lines the lines to write, null entries produce blank lines. 4087 * @param lineEnding the line separator to use, null is system default. 4088 * @param writer the {@link Writer} to write to, not null, not closed. 4089 * @throws NullPointerException if the input is null. 4090 * @throws IOException if an I/O error occurs. 4091 * @since 1.1 4092 */ 4093 public static void writeLines(final Collection<?> lines, String lineEnding, final Writer writer) throws IOException { 4094 if (lines == null) { 4095 return; 4096 } 4097 if (lineEnding == null) { 4098 lineEnding = System.lineSeparator(); 4099 } 4100 for (final Object line : lines) { 4101 if (line != null) { 4102 writer.write(line.toString()); 4103 } 4104 writer.write(lineEnding); 4105 } 4106 } 4107 4108 /** 4109 * Returns the given Appendable if it is already a {@link Writer}, otherwise creates a Writer wrapper around the 4110 * given Appendable. 4111 * 4112 * @param appendable the Appendable to wrap or return (not null). 4113 * @return the given Appendable or a Writer wrapper around the given Appendable. 4114 * @throws NullPointerException if the input parameter is null. 4115 * @since 2.7 4116 */ 4117 public static Writer writer(final Appendable appendable) { 4118 Objects.requireNonNull(appendable, "appendable"); 4119 if (appendable instanceof Writer) { 4120 return (Writer) appendable; 4121 } 4122 if (appendable instanceof StringBuilder) { 4123 return new StringBuilderWriter((StringBuilder) appendable); 4124 } 4125 return new AppendableWriter<>(appendable); 4126 } 4127 4128 /** 4129 * Instances should NOT be constructed in standard programming. 4130 * 4131 * @deprecated TODO Make private in 3.0. 4132 */ 4133 @Deprecated 4134 public IOUtils() { //NOSONAR 4135 // empty 4136 } 4137 4138}