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