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