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