001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.io;
019
020import java.io.BufferedInputStream;
021import java.io.BufferedOutputStream;
022import java.io.BufferedReader;
023import java.io.BufferedWriter;
024import java.io.ByteArrayInputStream;
025import java.io.CharArrayWriter;
026import java.io.Closeable;
027import java.io.EOFException;
028import java.io.File;
029import java.io.IOException;
030import java.io.InputStream;
031import java.io.InputStreamReader;
032import java.io.OutputStream;
033import java.io.OutputStreamWriter;
034import java.io.PipedInputStream;
035import java.io.PipedOutputStream;
036import java.io.Reader;
037import java.io.UncheckedIOException;
038import java.io.Writer;
039import java.net.HttpURLConnection;
040import java.net.ServerSocket;
041import java.net.Socket;
042import java.net.URI;
043import java.net.URL;
044import java.net.URLConnection;
045import java.nio.ByteBuffer;
046import java.nio.CharBuffer;
047import java.nio.channels.Channels;
048import java.nio.channels.ReadableByteChannel;
049import java.nio.channels.Selector;
050import java.nio.charset.Charset;
051import java.nio.charset.StandardCharsets;
052import java.nio.file.Files;
053import java.util.Arrays;
054import java.util.Collection;
055import java.util.Iterator;
056import java.util.List;
057import java.util.Objects;
058import java.util.function.Consumer;
059import java.util.function.Supplier;
060import java.util.stream.Collectors;
061import java.util.stream.Stream;
062import java.util.zip.InflaterInputStream;
063
064import org.apache.commons.io.channels.FileChannels;
065import org.apache.commons.io.function.IOConsumer;
066import org.apache.commons.io.function.IOSupplier;
067import org.apache.commons.io.function.IOTriFunction;
068import org.apache.commons.io.input.BoundedInputStream;
069import org.apache.commons.io.input.CharSequenceReader;
070import org.apache.commons.io.input.QueueInputStream;
071import org.apache.commons.io.output.AppendableWriter;
072import org.apache.commons.io.output.ByteArrayOutputStream;
073import org.apache.commons.io.output.NullOutputStream;
074import org.apache.commons.io.output.NullWriter;
075import org.apache.commons.io.output.StringBuilderWriter;
076import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
077
078/**
079 * General IO stream manipulation utilities.
080 * <p>
081 * This class provides static utility methods for input/output operations.
082 * </p>
083 * <ul>
084 * <li>closeQuietly - these methods close a stream ignoring nulls and exceptions</li>
085 * <li>toXxx/read - these methods read data from a stream</li>
086 * <li>write - these methods write data to a stream</li>
087 * <li>copy - these methods copy all the data from one stream to another</li>
088 * <li>contentEquals - these methods compare the content of two streams</li>
089 * </ul>
090 * <p>
091 * The byte-to-char methods and char-to-byte methods involve a conversion step. Two methods are provided in each case, one that uses the platform default
092 * encoding and the other which allows you to specify an encoding. You are encouraged to always specify an encoding because relying on the platform default can
093 * lead to unexpected results, for example when moving from development to production.
094 * </p>
095 * <p>
096 * All the methods in this class that read a stream are buffered internally. This means that there is no cause to use a {@link BufferedInputStream} or
097 * {@link BufferedReader}. The default buffer size of 4K has been shown to be efficient in tests.
098 * </p>
099 * <p>
100 * The various copy methods all delegate the actual copying to one of the following methods:
101 * </p>
102 * <ul>
103 * <li>{@link #copyLarge(InputStream, OutputStream, byte[])}</li>
104 * <li>{@link #copyLarge(InputStream, OutputStream, long, long, byte[])}</li>
105 * <li>{@link #copyLarge(Reader, Writer, char[])}</li>
106 * <li>{@link #copyLarge(Reader, Writer, long, long, char[])}</li>
107 * </ul>
108 * For example, {@link #copy(InputStream, OutputStream)} calls {@link #copyLarge(InputStream, OutputStream)} which calls
109 * {@link #copy(InputStream, OutputStream, int)} which creates the buffer and calls {@link #copyLarge(InputStream, OutputStream, byte[])}.
110 * <p>
111 * Applications can re-use buffers by using the underlying methods directly. This may improve performance for applications that need to do a lot of copying.
112 * </p>
113 * <p>
114 * Wherever possible, the methods in this class do <em>not</em> flush or close the stream. This is to avoid making non-portable assumptions about the streams'
115 * origin and further use. Thus the caller is still responsible for closing streams after use.
116 * </p>
117 * <p>
118 * Provenance: Excalibur.
119 * </p>
120 */
121public class IOUtils {
122    // NOTE: This class is focused on InputStream, OutputStream, Reader and
123    // Writer. Each method should take at least one of these as a parameter,
124    // or return one of them.
125
126    /**
127     * Holder for per-thread internal scratch buffer.
128     * <p>
129     * Buffers are created lazily and reused within the same thread to reduce allocation overhead. In the rare case of reentrant access, a temporary buffer is
130     * allocated to avoid data corruption.
131     * </p>
132     * <p>
133     * Typical usage:
134     * </p>
135     *
136     * <pre>{@code
137     * try (ScratchBytes scratch = ScratchBytes.get()) {
138     *     // use the buffer
139     *     byte[] bytes = scratch.array();
140     *     // ...
141     * }
142     * }</pre>
143     */
144    static final class ScratchBytes implements AutoCloseable {
145
146        /**
147         * Wraps an internal byte array. [0] boolean in use. [1] byte[] buffer.
148         */
149        private static final ThreadLocal<Object[]> LOCAL = ThreadLocal.withInitial(() -> new Object[] { false, byteArray() });
150
151        private static final ScratchBytes INSTANCE = new ScratchBytes(null);
152
153        /**
154         * Gets the internal byte array buffer.
155         *
156         * @return the internal byte array buffer.
157         */
158        static ScratchBytes get() {
159            final Object[] holder = LOCAL.get();
160            // If already in use, return a new array
161            if ((boolean) holder[0]) {
162                return new ScratchBytes(byteArray());
163            }
164            holder[0] = true;
165            return INSTANCE;
166        }
167
168        /**
169         * The buffer, or null if using the thread-local buffer.
170         */
171        private final byte[] buffer;
172
173        private ScratchBytes(final byte[] buffer) {
174            this.buffer = buffer;
175        }
176
177        byte[] array() {
178            return buffer != null ? buffer : (byte[]) LOCAL.get()[1];
179        }
180
181        /**
182         * If the buffer is the internal array, clear and release it for reuse.
183         */
184        @Override
185        public void close() {
186            if (buffer == null) {
187                final Object[] holder = LOCAL.get();
188                Arrays.fill((byte[]) holder[1], (byte) 0);
189                holder[0] = false;
190            }
191        }
192    }
193
194    /**
195     * Holder for per-thread internal scratch buffer.
196     * <p>
197     * Buffers are created lazily and reused within the same thread to reduce allocation overhead. In the rare case of reentrant access, a temporary buffer is
198     * allocated to avoid data corruption.
199     * </p>
200     * <p>
201     * Typical usage:
202     * </p>
203     *
204     * <pre>{@code
205     * try (ScratchChars scratch = ScratchChars.get()) {
206     *     // use the buffer
207     *     char[] bytes = scratch.array();
208     *     // ...
209     * }
210     * }</pre>
211     */
212    static final class ScratchChars implements AutoCloseable {
213
214        /**
215         * Wraps an internal char array. [0] boolean in use. [1] char[] buffer.
216         */
217        private static final ThreadLocal<Object[]> LOCAL = ThreadLocal.withInitial(() -> new Object[] { false, charArray() });
218
219        private static final ScratchChars INSTANCE = new ScratchChars(null);
220
221        /**
222         * Gets the internal char array buffer.
223         *
224         * @return the internal char array buffer.
225         */
226        static ScratchChars get() {
227            final Object[] holder = LOCAL.get();
228            // If already in use, return a new array
229            if ((boolean) holder[0]) {
230                return new ScratchChars(charArray());
231            }
232            holder[0] = true;
233            return INSTANCE;
234        }
235
236        /**
237         * The buffer, or null if using the thread-local buffer.
238         */
239        private final char[] buffer;
240
241        private ScratchChars(final char[] buffer) {
242            this.buffer = buffer;
243        }
244
245        char[] array() {
246            return buffer != null ? buffer : (char[]) LOCAL.get()[1];
247        }
248
249        /**
250         * If the buffer is the internal array, clear and release it for reuse.
251         */
252        @Override
253        public void close() {
254            if (buffer == null) {
255                final Object[] holder = LOCAL.get();
256                Arrays.fill((char[]) holder[1], (char) 0);
257                holder[0] = false;
258            }
259        }
260    }
261
262    /**
263     * CR char '{@value}'.
264     *
265     * @since 2.9.0
266     */
267    public static final int CR = '\r';
268
269    /**
270     * The default buffer size ({@value}) to use in copy methods.
271     */
272    public static final int DEFAULT_BUFFER_SIZE = 8192;
273
274    /**
275     * The system directory separator character.
276     */
277    public static final char DIR_SEPARATOR = File.separatorChar;
278
279    /**
280     * The Unix directory separator character '{@value}'.
281     */
282    public static final char DIR_SEPARATOR_UNIX = '/';
283
284    /**
285     * The Windows directory separator character '{@value}'.
286     */
287    public static final char DIR_SEPARATOR_WINDOWS = '\\';
288
289    /**
290     * A singleton empty byte array.
291     *
292     * @since 2.9.0
293     */
294    public static final byte[] EMPTY_BYTE_ARRAY = {};
295
296    /**
297     * Represents the end-of-file (or stream) value {@value}.
298     *
299     * @since 2.5 (made public)
300     */
301    public static final int EOF = -1;
302
303    /**
304     * LF char '{@value}'.
305     *
306     * @since 2.9.0
307     */
308    public static final int LF = '\n';
309
310    /**
311     * The system line separator string.
312     *
313     * @deprecated Use {@link System#lineSeparator()}.
314     */
315    @Deprecated
316    public static final String LINE_SEPARATOR = System.lineSeparator();
317
318    /**
319     * The Unix line separator string.
320     *
321     * @see StandardLineSeparator#LF
322     */
323    public static final String LINE_SEPARATOR_UNIX = StandardLineSeparator.LF.getString();
324
325    /**
326     * The Windows line separator string.
327     *
328     * @see StandardLineSeparator#CRLF
329     */
330    public static final String LINE_SEPARATOR_WINDOWS = StandardLineSeparator.CRLF.getString();
331
332    /**
333     * The maximum size of an array in many Java VMs.
334     * <p>
335     * The constant is copied from OpenJDK's {@code jdk.internal.util.ArraysSupport#SOFT_MAX_ARRAY_LENGTH}.
336     * </p>
337     *
338     * @since 2.21.0
339     */
340    public static final int SOFT_MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;
341
342    /**
343     * Returns the given InputStream if it is already a {@link BufferedInputStream}, otherwise creates a BufferedInputStream from the given InputStream.
344     *
345     * @param inputStream the InputStream to wrap or return (not null).
346     * @return the given InputStream or a new {@link BufferedInputStream} for the given InputStream.
347     * @throws NullPointerException if the input parameter is null.
348     * @since 2.5
349     */
350    @SuppressWarnings("resource") // parameter null check
351    public static BufferedInputStream buffer(final InputStream inputStream) {
352        // reject null early on rather than waiting for IO operation to fail
353        // not checked by BufferedInputStream
354        Objects.requireNonNull(inputStream, "inputStream");
355        return inputStream instanceof BufferedInputStream ? (BufferedInputStream) inputStream : new BufferedInputStream(inputStream);
356    }
357
358    /**
359     * Returns the given InputStream if it is already a {@link BufferedInputStream}, otherwise creates a BufferedInputStream from the given InputStream.
360     *
361     * @param inputStream the InputStream to wrap or return (not null).
362     * @param size        the buffer size, if a new BufferedInputStream is created.
363     * @return the given InputStream or a new {@link BufferedInputStream} for the given InputStream.
364     * @throws NullPointerException if the input parameter is null.
365     * @since 2.5
366     */
367    @SuppressWarnings("resource") // parameter null check
368    public static BufferedInputStream buffer(final InputStream inputStream, final int size) {
369        // reject null early on rather than waiting for IO operation to fail
370        // not checked by BufferedInputStream
371        Objects.requireNonNull(inputStream, "inputStream");
372        return inputStream instanceof BufferedInputStream ? (BufferedInputStream) inputStream : new BufferedInputStream(inputStream, size);
373    }
374
375    /**
376     * Returns the given OutputStream if it is already a {@link BufferedOutputStream}, otherwise creates a BufferedOutputStream from the given OutputStream.
377     *
378     * @param outputStream the OutputStream to wrap or return (not null).
379     * @return the given OutputStream or a new {@link BufferedOutputStream} for the given OutputStream.
380     * @throws NullPointerException if the input parameter is null.
381     * @since 2.5
382     */
383    @SuppressWarnings("resource") // parameter null check
384    public static BufferedOutputStream buffer(final OutputStream outputStream) {
385        // reject null early on rather than waiting for IO operation to fail
386        // not checked by BufferedInputStream
387        Objects.requireNonNull(outputStream, "outputStream");
388        return outputStream instanceof BufferedOutputStream ? (BufferedOutputStream) outputStream : new BufferedOutputStream(outputStream);
389    }
390
391    /**
392     * Returns the given OutputStream if it is already a {@link BufferedOutputStream}, otherwise creates a BufferedOutputStream from the given OutputStream.
393     *
394     * @param outputStream the OutputStream to wrap or return (not null).
395     * @param size         the buffer size, if a new BufferedOutputStream is created.
396     * @return the given OutputStream or a new {@link BufferedOutputStream} for the given OutputStream.
397     * @throws NullPointerException if the input parameter is null.
398     * @since 2.5
399     */
400    @SuppressWarnings("resource") // parameter null check
401    public static BufferedOutputStream buffer(final OutputStream outputStream, final int size) {
402        // reject null early on rather than waiting for IO operation to fail
403        // not checked by BufferedInputStream
404        Objects.requireNonNull(outputStream, "outputStream");
405        return outputStream instanceof BufferedOutputStream ? (BufferedOutputStream) outputStream : new BufferedOutputStream(outputStream, size);
406    }
407
408    /**
409     * Returns the given reader if it is already a {@link BufferedReader}, otherwise creates a BufferedReader from the given reader.
410     *
411     * @param reader the reader to wrap or return (not null).
412     * @return the given reader or a new {@link BufferedReader} for the given reader.
413     * @throws NullPointerException if the input parameter is null.
414     * @since 2.5
415     */
416    public static BufferedReader buffer(final Reader reader) {
417        return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
418    }
419
420    /**
421     * Returns the given reader if it is already a {@link BufferedReader}, otherwise creates a BufferedReader from the given reader.
422     *
423     * @param reader the reader to wrap or return (not null).
424     * @param size   the buffer size, if a new BufferedReader is created.
425     * @return the given reader or a new {@link BufferedReader} for the given reader.
426     * @throws NullPointerException if the input parameter is null.
427     * @since 2.5
428     */
429    public static BufferedReader buffer(final Reader reader, final int size) {
430        return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader, size);
431    }
432
433    /**
434     * Returns the given Writer if it is already a {@link BufferedWriter}, otherwise creates a BufferedWriter from the given Writer.
435     *
436     * @param writer the Writer to wrap or return (not null).
437     * @return the given Writer or a new {@link BufferedWriter} for the given Writer.
438     * @throws NullPointerException if the input parameter is null.
439     * @since 2.5
440     */
441    public static BufferedWriter buffer(final Writer writer) {
442        return writer instanceof BufferedWriter ? (BufferedWriter) writer : new BufferedWriter(writer);
443    }
444
445    /**
446     * Returns the given Writer if it is already a {@link BufferedWriter}, otherwise creates a BufferedWriter from the given Writer.
447     *
448     * @param writer the Writer to wrap or return (not null).
449     * @param size   the buffer size, if a new BufferedWriter is created.
450     * @return the given Writer or a new {@link BufferedWriter} for the given Writer.
451     * @throws NullPointerException if the input parameter is null.
452     * @since 2.5
453     */
454    public static BufferedWriter buffer(final Writer writer, final int size) {
455        return writer instanceof BufferedWriter ? (BufferedWriter) writer : new BufferedWriter(writer, size);
456    }
457
458    /**
459     * Returns a new byte array of size {@link #DEFAULT_BUFFER_SIZE}.
460     *
461     * @return a new byte array of size {@link #DEFAULT_BUFFER_SIZE}.
462     * @since 2.9.0
463     */
464    public static byte[] byteArray() {
465        return byteArray(DEFAULT_BUFFER_SIZE);
466    }
467
468    /**
469     * Returns a new byte array of the given size. TODO Consider guarding or warning against large allocations.
470     *
471     * @param size array size.
472     * @return a new byte array of the given size.
473     * @throws NegativeArraySizeException if the size is negative.
474     * @since 2.9.0
475     */
476    public static byte[] byteArray(final int size) {
477        return new byte[size];
478    }
479
480    /**
481     * Returns a new char array of size {@link #DEFAULT_BUFFER_SIZE}.
482     *
483     * @return a new char array of size {@link #DEFAULT_BUFFER_SIZE}.
484     * @since 2.9.0
485     */
486    private static char[] charArray() {
487        return charArray(DEFAULT_BUFFER_SIZE);
488    }
489
490    /**
491     * Returns a new char array of the given size. TODO Consider guarding or warning against large allocations.
492     *
493     * @param size array size.
494     * @return a new char array of the given size.
495     * @since 2.9.0
496     */
497    private static char[] charArray(final int size) {
498        return new char[size];
499    }
500
501    /**
502     * Validates that the sub-range {@code [off, off + len)} is within the bounds of the given array.
503     * <p>
504     * The range is valid if all of the following hold:
505     * </p>
506     * <ul>
507     * <li>{@code off >= 0}</li>
508     * <li>{@code len >= 0}</li>
509     * <li>{@code off + len <= array.length}</li>
510     * </ul>
511     * <p>
512     * If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.
513     * </p>
514     * <p>
515     * Typical usage in {@link InputStream#read(byte[], int, int)} and {@link OutputStream#write(byte[], int, int)} implementations:
516     * </p>
517     *
518     * <pre>
519     * <code>
520     * public int read(byte[] b, int off, int len) throws IOException {
521     *     IOUtils.checkFromIndexSize(b, off, len);
522     *     if (len == 0) {
523     *         return 0;
524     *     }
525     *     ensureOpen();
526     *     // perform read...
527     * }
528     *
529     * public void write(byte[] b, int off, int len) throws IOException {
530     *     IOUtils.checkFromIndexSize(b, off, len);
531     *     if (len == 0) {
532     *         return;
533     *     }
534     *     ensureOpen();
535     *     // perform write...
536     * }
537     * </code>
538     * </pre>
539     *
540     * @param array the array against which the range is validated.
541     * @param off   the starting offset into the array (inclusive).
542     * @param len   the number of elements to access.
543     * @throws NullPointerException      if {@code array} is {@code null}.
544     * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code array}.
545     * @see InputStream#read(byte[], int, int)
546     * @see OutputStream#write(byte[], int, int)
547     * @since 2.21.0
548     */
549    public static void checkFromIndexSize(final byte[] array, final int off, final int len) {
550        checkFromIndexSize(off, len, Objects.requireNonNull(array, "byte array").length);
551    }
552
553    /**
554     * Validates that the sub-range {@code [off, off + len)} is within the bounds of the given array.
555     * <p>
556     * The range is valid if all of the following hold:
557     * </p>
558     * <ul>
559     * <li>{@code off >= 0}</li>
560     * <li>{@code len >= 0}</li>
561     * <li>{@code off + len <= array.length}</li>
562     * </ul>
563     * <p>
564     * If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.
565     * </p>
566     * <p>
567     * Typical usage in {@link Reader#read(char[], int, int)} and {@link Writer#write(char[], int, int)} implementations:
568     * </p>
569     *
570     * <pre>
571     * <code>
572     * public int read(char[] cbuf, int off, int len) throws IOException {
573     *     ensureOpen();
574     *     IOUtils.checkFromIndexSize(cbuf, off, len);
575     *     if (len == 0) {
576     *         return 0;
577     *     }
578     *     // perform read...
579     * }
580     *
581     * public void write(char[] cbuf, int off, int len) throws IOException {
582     *     ensureOpen();
583     *     IOUtils.checkFromIndexSize(cbuf, off, len);
584     *     if (len == 0) {
585     *         return;
586     *     }
587     *     // perform write...
588     * }
589     * </code>
590     * </pre>
591     *
592     * @param array the array against which the range is validated.
593     * @param off   the starting offset into the array (inclusive).
594     * @param len   the number of characters to access.
595     * @throws NullPointerException      if {@code array} is {@code null}.
596     * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code array}.
597     * @see Reader#read(char[], int, int)
598     * @see Writer#write(char[], int, int)
599     * @since 2.21.0
600     */
601    public static void checkFromIndexSize(final char[] array, final int off, final int len) {
602        checkFromIndexSize(off, len, Objects.requireNonNull(array, "char array").length);
603    }
604
605    static void checkFromIndexSize(final int off, final int len, final int arrayLength) {
606        if ((off | len | arrayLength) < 0 || arrayLength - len < off) {
607            throw new IndexOutOfBoundsException(String.format("Range [%s, %<s + %s) out of bounds for length %s", off, len, arrayLength));
608        }
609    }
610
611    /**
612     * Validates that the sub-range {@code [off, off + len)} is within the bounds of the given string.
613     * <p>
614     * The range is valid if all of the following hold:
615     * </p>
616     * <ul>
617     * <li>{@code off >= 0}</li>
618     * <li>{@code len >= 0}</li>
619     * <li>{@code off + len <= str.length()}</li>
620     * </ul>
621     * <p>
622     * If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.
623     * </p>
624     * <p>
625     * Typical usage in {@link Writer#write(String, int, int)} implementations:
626     * </p>
627     *
628     * <pre>
629     * <code>
630     * public void write(String str, int off, int len) throws IOException {
631     *     IOUtils.checkFromIndexSize(str, off, len);
632     *     if (len == 0) {
633     *         return;
634     *     }
635     *     // perform write...
636     * }
637     * </code>
638     * </pre>
639     *
640     * @param str the string against which the range is validated.
641     * @param off the starting offset into the string (inclusive).
642     * @param len the number of characters to write.
643     * @throws NullPointerException      if {@code str} is {@code null}.
644     * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code str}.
645     * @see Writer#write(String, int, int)
646     * @since 2.21.0
647     */
648    public static void checkFromIndexSize(final String str, final int off, final int len) {
649        checkFromIndexSize(off, len, Objects.requireNonNull(str, "str").length());
650    }
651
652    /**
653     * Validates that the sub-sequence {@code [fromIndex, toIndex)} is within the bounds of the given {@link CharSequence}.
654     * <p>
655     * The sub-sequence is valid if all of the following hold:
656     * </p>
657     * <ul>
658     * <li>{@code fromIndex >= 0}</li>
659     * <li>{@code fromIndex <= toIndex}</li>
660     * <li>{@code toIndex <= seq.length()}</li>
661     * </ul>
662     * <p>
663     * If {@code seq} is {@code null}, it is treated as the literal string {@code "null"} (length {@code 4}).
664     * </p>
665     * <p>
666     * If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.
667     * </p>
668     * <p>
669     * Typical usage in {@link Appendable#append(CharSequence, int, int)} implementations:
670     * </p>
671     *
672     * <pre>
673     * <code>
674     * public Appendable append(CharSequence csq, int start, int end) throws IOException {
675     *     IOUtils.checkFromToIndex(csq, start, end);
676     *     // perform append...
677     *     return this;
678     * }
679     * </code>
680     * </pre>
681     *
682     * @param seq       the character sequence to validate (may be {@code null}, treated as {@code "null"}).
683     * @param fromIndex the starting index (inclusive).
684     * @param toIndex   the ending index (exclusive).
685     * @throws IndexOutOfBoundsException if the range {@code [fromIndex, toIndex)} is out of bounds for {@code seq}.
686     * @see Appendable#append(CharSequence, int, int)
687     * @since 2.21.0
688     */
689    public static void checkFromToIndex(final CharSequence seq, final int fromIndex, final int toIndex) {
690        checkFromToIndex(fromIndex, toIndex, seq != null ? seq.length() : 4);
691    }
692
693    static void checkFromToIndex(final int fromIndex, final int toIndex, final int length) {
694        if (fromIndex < 0 || toIndex < fromIndex || length < toIndex) {
695            throw new IndexOutOfBoundsException(String.format("Range [%s, %s) out of bounds for length %s", fromIndex, toIndex, length));
696        }
697    }
698
699    /**
700     * Clears any state.
701     * <ul>
702     * <li>Removes the current thread's value for thread-local variables.</li>
703     * <li>Sets static scratch arrays to 0s.</li>
704     * </ul>
705     *
706     * @see IO#clear()
707     */
708    static void clear() {
709        ScratchBytes.LOCAL.remove();
710        ScratchChars.LOCAL.remove();
711    }
712
713    /**
714     * Closes the given {@link Closeable} as a null-safe operation.
715     *
716     * @param closeable The resource to close, may be null.
717     * @throws IOException if an I/O error occurs.
718     * @since 2.7
719     */
720    public static void close(final Closeable closeable) throws IOException {
721        if (closeable != null) {
722            closeable.close();
723        }
724    }
725
726    /**
727     * Closes the given {@link Closeable}s as null-safe operations.
728     *
729     * @param closeables The resource(s) to close, may be null.
730     * @throws IOExceptionList if an I/O error occurs.
731     * @since 2.8.0
732     */
733    public static void close(final Closeable... closeables) throws IOExceptionList {
734        IOConsumer.forAll(IOUtils::close, closeables);
735    }
736
737    /**
738     * Closes the given {@link Closeable} as a null-safe operation.
739     *
740     * @param closeable The resource to close, may be null.
741     * @param consumer  Consume the IOException thrown by {@link Closeable#close()}.
742     * @throws IOException if an I/O error occurs.
743     * @since 2.7
744     */
745    public static void close(final Closeable closeable, final IOConsumer<IOException> consumer) throws IOException {
746        if (closeable != null) {
747            try {
748                closeable.close();
749            } catch (final IOException e) {
750                if (consumer != null) {
751                    consumer.accept(e);
752                }
753            } catch (final Exception e) {
754                if (consumer != null) {
755                    consumer.accept(new IOException(e));
756                }
757            }
758        }
759    }
760
761    /**
762     * Closes a URLConnection.
763     *
764     * @param conn the connection to close.
765     * @since 2.4
766     */
767    public static void close(final URLConnection conn) {
768        if (conn instanceof HttpURLConnection) {
769            ((HttpURLConnection) conn).disconnect();
770        }
771    }
772
773    /**
774     * Avoids the need to type cast.
775     *
776     * @param closeable the object to close, may be null.
777     */
778    private static void closeQ(final Closeable closeable) {
779        closeQuietly(closeable, (Consumer<Exception>) null);
780    }
781
782    /**
783     * Closes a {@link Closeable} unconditionally.
784     * <p>
785     * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored. This is typically used in finally blocks.
786     * <p>
787     * Example code:
788     * </p>
789     *
790     * <pre>
791     * Closeable closeable = null;
792     * try {
793     *     closeable = new FileReader(&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}