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