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