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.FileOutputStream;
029import java.io.IOException;
030import java.io.InputStream;
031import java.io.InputStreamReader;
032import java.io.OutputStream;
033import java.io.OutputStreamWriter;
034import java.io.Reader;
035import java.io.Writer;
036import java.net.HttpURLConnection;
037import java.net.ServerSocket;
038import java.net.Socket;
039import java.net.URI;
040import java.net.URL;
041import java.net.URLConnection;
042import java.nio.ByteBuffer;
043import java.nio.CharBuffer;
044import java.nio.channels.ReadableByteChannel;
045import java.nio.channels.Selector;
046import java.nio.charset.Charset;
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 (FileOutputStream outputStream = new FileOutputStream(Objects.requireNonNull(file, "file"))) {
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     * @throws IOException Never thrown.
1598     * @since 2.3
1599     */
1600    public static LineIterator lineIterator(final InputStream input, final Charset charset) throws IOException {
1601        return new LineIterator(new InputStreamReader(input, Charsets.toCharset(charset)));
1602    }
1603
1604    /**
1605     * Returns an Iterator for the lines in an {@code InputStream}, using
1606     * the character encoding specified (or default encoding if null).
1607     * <p>
1608     * {@code LineIterator} holds a reference to the open
1609     * {@code InputStream} specified here. When you have finished with
1610     * the iterator you should close the stream to free internal resources.
1611     * This can be done by closing the stream directly, or by calling
1612     * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
1613     * <p>
1614     * The recommended usage pattern is:
1615     * <pre>
1616     * try {
1617     *   LineIterator it = IOUtils.lineIterator(stream, "UTF-8");
1618     *   while (it.hasNext()) {
1619     *     String line = it.nextLine();
1620     *     /// do something with line
1621     *   }
1622     * } finally {
1623     *   IOUtils.closeQuietly(stream);
1624     * }
1625     * </pre>
1626     *
1627     * @param input the {@code InputStream} to read from, not null
1628     * @param charsetName the encoding to use, null means platform default
1629     * @return an Iterator of the lines in the reader, never null
1630     * @throws IllegalArgumentException                     if the input is null
1631     * @throws IOException                                  if an I/O error occurs, such as if the encoding is invalid
1632     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
1633     *                                                      .UnsupportedEncodingException} in version 2.2 if the
1634     *                                                      encoding is not supported.
1635     * @since 1.2
1636     */
1637    public static LineIterator lineIterator(final InputStream input, final String charsetName) throws IOException {
1638        return lineIterator(input, Charsets.toCharset(charsetName));
1639    }
1640
1641    /**
1642     * Returns an Iterator for the lines in a {@code Reader}.
1643     * <p>
1644     * {@code LineIterator} holds a reference to the open
1645     * {@code Reader} specified here. When you have finished with the
1646     * iterator you should close the reader to free internal resources.
1647     * This can be done by closing the reader directly, or by calling
1648     * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
1649     * <p>
1650     * The recommended usage pattern is:
1651     * <pre>
1652     * try {
1653     *   LineIterator it = IOUtils.lineIterator(reader);
1654     *   while (it.hasNext()) {
1655     *     String line = it.nextLine();
1656     *     /// do something with line
1657     *   }
1658     * } finally {
1659     *   IOUtils.closeQuietly(reader);
1660     * }
1661     * </pre>
1662     *
1663     * @param reader the {@code Reader} to read from, not null
1664     * @return an Iterator of the lines in the reader, never null
1665     * @throws IllegalArgumentException if the reader is null
1666     * @since 1.2
1667     */
1668    public static LineIterator lineIterator(final Reader reader) {
1669        return new LineIterator(reader);
1670    }
1671
1672    /**
1673     * Reads bytes from an input stream.
1674     * This implementation guarantees that it will read as many bytes
1675     * as possible before giving up; this may not always be the case for
1676     * subclasses of {@link InputStream}.
1677     *
1678     * @param input where to read input from
1679     * @param buffer destination
1680     * @return actual length read; may be less than requested if EOF was reached
1681     * @throws IOException if a read error occurs
1682     * @since 2.2
1683     */
1684    public static int read(final InputStream input, final byte[] buffer) throws IOException {
1685        return read(input, buffer, 0, buffer.length);
1686    }
1687
1688    /**
1689     * Reads bytes from an input stream.
1690     * This implementation guarantees that it will read as many bytes
1691     * as possible before giving up; this may not always be the case for
1692     * subclasses of {@link InputStream}.
1693     *
1694     * @param input where to read input from
1695     * @param buffer destination
1696     * @param offset initial offset into buffer
1697     * @param length length to read, must be &gt;= 0
1698     * @return actual length read; may be less than requested if EOF was reached
1699     * @throws IOException if a read error occurs
1700     * @since 2.2
1701     */
1702    public static int read(final InputStream input, final byte[] buffer, final int offset, final int length)
1703            throws IOException {
1704        if (length < 0) {
1705            throw new IllegalArgumentException("Length must not be negative: " + length);
1706        }
1707        int remaining = length;
1708        while (remaining > 0) {
1709            final int location = length - remaining;
1710            final int count = input.read(buffer, offset + location, remaining);
1711            if (EOF == count) { // EOF
1712                break;
1713            }
1714            remaining -= count;
1715        }
1716        return length - remaining;
1717    }
1718
1719    /**
1720     * Reads bytes from a ReadableByteChannel.
1721     * <p>
1722     * This implementation guarantees that it will read as many bytes
1723     * as possible before giving up; this may not always be the case for
1724     * subclasses of {@link ReadableByteChannel}.
1725     *
1726     * @param input the byte channel to read
1727     * @param buffer byte buffer destination
1728     * @return the actual length read; may be less than requested if EOF was reached
1729     * @throws IOException if a read error occurs
1730     * @since 2.5
1731     */
1732    public static int read(final ReadableByteChannel input, final ByteBuffer buffer) throws IOException {
1733        final int length = buffer.remaining();
1734        while (buffer.remaining() > 0) {
1735            final int count = input.read(buffer);
1736            if (EOF == count) { // EOF
1737                break;
1738            }
1739        }
1740        return length - buffer.remaining();
1741    }
1742
1743    /**
1744     * Reads characters from an input character stream.
1745     * This implementation guarantees that it will read as many characters
1746     * as possible before giving up; this may not always be the case for
1747     * subclasses of {@link Reader}.
1748     *
1749     * @param reader where to read input from
1750     * @param buffer destination
1751     * @return actual length read; may be less than requested if EOF was reached
1752     * @throws IOException if a read error occurs
1753     * @since 2.2
1754     */
1755    public static int read(final Reader reader, final char[] buffer) throws IOException {
1756        return read(reader, buffer, 0, buffer.length);
1757    }
1758
1759    /**
1760     * Reads characters from an input character stream.
1761     * This implementation guarantees that it will read as many characters
1762     * as possible before giving up; this may not always be the case for
1763     * subclasses of {@link Reader}.
1764     *
1765     * @param reader where to read input from
1766     * @param buffer destination
1767     * @param offset initial offset into buffer
1768     * @param length length to read, must be &gt;= 0
1769     * @return actual length read; may be less than requested if EOF was reached
1770     * @throws IOException if a read error occurs
1771     * @since 2.2
1772     */
1773    public static int read(final Reader reader, final char[] buffer, final int offset, final int length)
1774            throws IOException {
1775        if (length < 0) {
1776            throw new IllegalArgumentException("Length must not be negative: " + length);
1777        }
1778        int remaining = length;
1779        while (remaining > 0) {
1780            final int location = length - remaining;
1781            final int count = reader.read(buffer, offset + location, remaining);
1782            if (EOF == count) { // EOF
1783                break;
1784            }
1785            remaining -= count;
1786        }
1787        return length - remaining;
1788    }
1789
1790    /**
1791     * Reads the requested number of bytes or fail if there are not enough left.
1792     * <p>
1793     * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
1794     * not read as many bytes as requested (most likely because of reaching EOF).
1795     *
1796     * @param input where to read input from
1797     * @param buffer destination
1798     *
1799     * @throws IOException              if there is a problem reading the file
1800     * @throws IllegalArgumentException if length is negative
1801     * @throws EOFException             if the number of bytes read was incorrect
1802     * @since 2.2
1803     */
1804    public static void readFully(final InputStream input, final byte[] buffer) throws IOException {
1805        readFully(input, buffer, 0, buffer.length);
1806    }
1807
1808    /**
1809     * Reads the requested number of bytes or fail if there are not enough left.
1810     * <p>
1811     * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
1812     * not read as many bytes as requested (most likely because of reaching EOF).
1813     *
1814     * @param input where to read input from
1815     * @param buffer destination
1816     * @param offset initial offset into buffer
1817     * @param length length to read, must be &gt;= 0
1818     *
1819     * @throws IOException              if there is a problem reading the file
1820     * @throws IllegalArgumentException if length is negative
1821     * @throws EOFException             if the number of bytes read was incorrect
1822     * @since 2.2
1823     */
1824    public static void readFully(final InputStream input, final byte[] buffer, final int offset, final int length)
1825            throws IOException {
1826        final int actual = read(input, buffer, offset, length);
1827        if (actual != length) {
1828            throw new EOFException("Length to read: " + length + " actual: " + actual);
1829        }
1830    }
1831
1832    /**
1833     * Reads the requested number of bytes or fail if there are not enough left.
1834     * <p>
1835     * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
1836     * not read as many bytes as requested (most likely because of reaching EOF).
1837     *
1838     * @param input where to read input from
1839     * @param length length to read, must be &gt;= 0
1840     * @return the bytes read from input
1841     * @throws IOException              if there is a problem reading the file
1842     * @throws IllegalArgumentException if length is negative
1843     * @throws EOFException             if the number of bytes read was incorrect
1844     * @since 2.5
1845     */
1846    public static byte[] readFully(final InputStream input, final int length) throws IOException {
1847        final byte[] buffer = IOUtils.byteArray(length);
1848        readFully(input, buffer, 0, buffer.length);
1849        return buffer;
1850    }
1851
1852    /**
1853     * Reads the requested number of bytes or fail if there are not enough left.
1854     * <p>
1855     * This allows for the possibility that {@link ReadableByteChannel#read(ByteBuffer)} may
1856     * not read as many bytes as requested (most likely because of reaching EOF).
1857     *
1858     * @param input the byte channel to read
1859     * @param buffer byte buffer destination
1860     * @throws IOException  if there is a problem reading the file
1861     * @throws EOFException if the number of bytes read was incorrect
1862     * @since 2.5
1863     */
1864    public static void readFully(final ReadableByteChannel input, final ByteBuffer buffer) throws IOException {
1865        final int expected = buffer.remaining();
1866        final int actual = read(input, buffer);
1867        if (actual != expected) {
1868            throw new EOFException("Length to read: " + expected + " actual: " + actual);
1869        }
1870    }
1871
1872    /**
1873     * Reads the requested number of characters or fail if there are not enough left.
1874     * <p>
1875     * This allows for the possibility that {@link Reader#read(char[], int, int)} may
1876     * not read as many characters as requested (most likely because of reaching EOF).
1877     *
1878     * @param reader where to read input from
1879     * @param buffer destination
1880     * @throws IOException              if there is a problem reading the file
1881     * @throws IllegalArgumentException if length is negative
1882     * @throws EOFException             if the number of characters read was incorrect
1883     * @since 2.2
1884     */
1885    public static void readFully(final Reader reader, final char[] buffer) throws IOException {
1886        readFully(reader, buffer, 0, buffer.length);
1887    }
1888
1889    /**
1890     * Reads the requested number of characters or fail if there are not enough left.
1891     * <p>
1892     * This allows for the possibility that {@link Reader#read(char[], int, int)} may
1893     * not read as many characters as requested (most likely because of reaching EOF).
1894     *
1895     * @param reader where to read input from
1896     * @param buffer destination
1897     * @param offset initial offset into buffer
1898     * @param length length to read, must be &gt;= 0
1899     * @throws IOException              if there is a problem reading the file
1900     * @throws IllegalArgumentException if length is negative
1901     * @throws EOFException             if the number of characters read was incorrect
1902     * @since 2.2
1903     */
1904    public static void readFully(final Reader reader, final char[] buffer, final int offset, final int length)
1905            throws IOException {
1906        final int actual = read(reader, buffer, offset, length);
1907        if (actual != length) {
1908            throw new EOFException("Length to read: " + length + " actual: " + actual);
1909        }
1910    }
1911
1912    /**
1913     * Gets the contents of an {@code InputStream} as a list of Strings,
1914     * one entry per line, using the default character encoding of the platform.
1915     * <p>
1916     * This method buffers the input internally, so there is no need to use a
1917     * {@code BufferedInputStream}.
1918     *
1919     * @param input the {@code InputStream} to read from, not null
1920     * @return the list of Strings, never null
1921     * @throws NullPointerException if the input is null
1922     * @throws IOException          if an I/O error occurs
1923     * @since 1.1
1924     * @deprecated 2.5 use {@link #readLines(InputStream, Charset)} instead
1925     */
1926    @Deprecated
1927    public static List<String> readLines(final InputStream input) throws IOException {
1928        return readLines(input, Charset.defaultCharset());
1929    }
1930
1931    /**
1932     * Gets the contents of an {@code InputStream} as a list of Strings,
1933     * one entry per line, using the specified character encoding.
1934     * <p>
1935     * This method buffers the input internally, so there is no need to use a
1936     * {@code BufferedInputStream}.
1937     *
1938     * @param input the {@code InputStream} to read from, not null
1939     * @param charset the charset to use, null means platform default
1940     * @return the list of Strings, never null
1941     * @throws NullPointerException if the input is null
1942     * @throws IOException          if an I/O error occurs
1943     * @since 2.3
1944     */
1945    public static List<String> readLines(final InputStream input, final Charset charset) throws IOException {
1946        final InputStreamReader reader = new InputStreamReader(input, Charsets.toCharset(charset));
1947        return readLines(reader);
1948    }
1949
1950    /**
1951     * Gets the contents of an {@code InputStream} as a list of Strings,
1952     * one entry per line, using the specified character encoding.
1953     * <p>
1954     * Character encoding names can be found at
1955     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1956     * <p>
1957     * This method buffers the input internally, so there is no need to use a
1958     * {@code BufferedInputStream}.
1959     *
1960     * @param input the {@code InputStream} to read from, not null
1961     * @param charsetName the name of the requested charset, null means platform default
1962     * @return the list of Strings, never null
1963     * @throws NullPointerException                         if the input is null
1964     * @throws IOException                                  if an I/O error occurs
1965     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
1966     *                                                      .UnsupportedEncodingException} in version 2.2 if the
1967     *                                                      encoding is not supported.
1968     * @since 1.1
1969     */
1970    public static List<String> readLines(final InputStream input, final String charsetName) throws IOException {
1971        return readLines(input, Charsets.toCharset(charsetName));
1972    }
1973
1974    /**
1975     * Gets the contents of a {@code Reader} as a list of Strings,
1976     * one entry per line.
1977     * <p>
1978     * This method buffers the input internally, so there is no need to use a
1979     * {@code BufferedReader}.
1980     *
1981     * @param reader the {@code Reader} to read from, not null
1982     * @return the list of Strings, never null
1983     * @throws NullPointerException if the input is null
1984     * @throws IOException          if an I/O error occurs
1985     * @since 1.1
1986     */
1987    @SuppressWarnings("resource") // reader wraps input and is the responsibility of the caller.
1988    public static List<String> readLines(final Reader reader) throws IOException {
1989        final BufferedReader bufReader = toBufferedReader(reader);
1990        final List<String> list = new ArrayList<>();
1991        String line;
1992        while ((line = bufReader.readLine()) != null) {
1993            list.add(line);
1994        }
1995        return list;
1996    }
1997
1998    /**
1999     * Gets the contents of a classpath resource as a byte array.
2000     *
2001     * <p>
2002     * It is expected the given {@code name} to be absolute. The
2003     * behavior is not well-defined otherwise.
2004     * </p>
2005     *
2006     * @param name name of the desired resource
2007     * @return the requested byte array
2008     * @throws IOException if an I/O error occurs.
2009     *
2010     * @since 2.6
2011     */
2012    public static byte[] resourceToByteArray(final String name) throws IOException {
2013        return resourceToByteArray(name, null);
2014    }
2015
2016    /**
2017     * Gets the contents of a classpath resource as a byte array.
2018     *
2019     * <p>
2020     * It is expected the given {@code name} to be absolute. The
2021     * behavior is not well-defined otherwise.
2022     * </p>
2023     *
2024     * @param name name of the desired resource
2025     * @param classLoader the class loader that the resolution of the resource is delegated to
2026     * @return the requested byte array
2027     * @throws IOException if an I/O error occurs.
2028     *
2029     * @since 2.6
2030     */
2031    public static byte[] resourceToByteArray(final String name, final ClassLoader classLoader) throws IOException {
2032        return toByteArray(resourceToURL(name, classLoader));
2033    }
2034
2035    /**
2036     * Gets the contents of a classpath resource as a String using the
2037     * specified character encoding.
2038     *
2039     * <p>
2040     * It is expected the given {@code name} to be absolute. The
2041     * behavior is not well-defined otherwise.
2042     * </p>
2043     *
2044     * @param name     name of the desired resource
2045     * @param charset the charset to use, null means platform default
2046     * @return the requested String
2047     * @throws IOException if an I/O error occurs.
2048     *
2049     * @since 2.6
2050     */
2051    public static String resourceToString(final String name, final Charset charset) throws IOException {
2052        return resourceToString(name, charset, null);
2053    }
2054
2055    /**
2056     * Gets the contents of a classpath resource as a String using the
2057     * specified character encoding.
2058     *
2059     * <p>
2060     * It is expected the given {@code name} to be absolute. The
2061     * behavior is not well-defined otherwise.
2062     * </p>
2063     *
2064     * @param name     name of the desired resource
2065     * @param charset the charset to use, null means platform default
2066     * @param classLoader the class loader that the resolution of the resource is delegated to
2067     * @return the requested String
2068     * @throws IOException if an I/O error occurs.
2069     *
2070     * @since 2.6
2071     */
2072    public static String resourceToString(final String name, final Charset charset, final ClassLoader classLoader) throws IOException {
2073        return toString(resourceToURL(name, classLoader), charset);
2074    }
2075
2076    /**
2077     * Gets a URL pointing to the given classpath resource.
2078     *
2079     * <p>
2080     * It is expected the given {@code name} to be absolute. The
2081     * behavior is not well-defined otherwise.
2082     * </p>
2083     *
2084     * @param name name of the desired resource
2085     * @return the requested URL
2086     * @throws IOException if an I/O error occurs.
2087     *
2088     * @since 2.6
2089     */
2090    public static URL resourceToURL(final String name) throws IOException {
2091        return resourceToURL(name, null);
2092    }
2093
2094    /**
2095     * Gets a URL pointing to the given classpath resource.
2096     *
2097     * <p>
2098     * It is expected the given {@code name} to be absolute. The
2099     * behavior is not well-defined otherwise.
2100     * </p>
2101     *
2102     * @param name        name of the desired resource
2103     * @param classLoader the class loader that the resolution of the resource is delegated to
2104     * @return the requested URL
2105     * @throws IOException if an I/O error occurs.
2106     *
2107     * @since 2.6
2108     */
2109    public static URL resourceToURL(final String name, final ClassLoader classLoader) throws IOException {
2110        // What about the thread context class loader?
2111        // What about the system class loader?
2112        final URL resource = classLoader == null ? IOUtils.class.getResource(name) : classLoader.getResource(name);
2113
2114        if (resource == null) {
2115            throw new IOException("Resource not found: " + name);
2116        }
2117
2118        return resource;
2119    }
2120
2121    /**
2122     * Skips bytes from an input byte stream.
2123     * This implementation guarantees that it will read as many bytes
2124     * as possible before giving up; this may not always be the case for
2125     * skip() implementations in subclasses of {@link InputStream}.
2126     * <p>
2127     * Note that the implementation uses {@link InputStream#read(byte[], int, int)} rather
2128     * than delegating to {@link InputStream#skip(long)}.
2129     * This means that the method may be considerably less efficient than using the actual skip implementation,
2130     * this is done to guarantee that the correct number of bytes are skipped.
2131     * </p>
2132     *
2133     * @param input byte stream to skip
2134     * @param toSkip number of bytes to skip.
2135     * @return number of bytes actually skipped.
2136     * @throws IOException              if there is a problem reading the file
2137     * @throws IllegalArgumentException if toSkip is negative
2138     * @see InputStream#skip(long)
2139     * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a>
2140     * @since 2.0
2141     */
2142    public static long skip(final InputStream input, final long toSkip) throws IOException {
2143        if (toSkip < 0) {
2144            throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
2145        }
2146        /*
2147         * N.B. no need to synchronize access to SKIP_BYTE_BUFFER: - we don't care if the buffer is created multiple
2148         * times (the data is ignored) - we always use the same size buffer, so if it it is recreated it will still be
2149         * OK (if the buffer size were variable, we would need to synch. to ensure some other thread did not create a
2150         * smaller one)
2151         */
2152        long remain = toSkip;
2153        while (remain > 0) {
2154            // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip()
2155            final byte[] byteArray = getByteArray();
2156            final long n = input.read(byteArray, 0, (int) Math.min(remain, byteArray.length));
2157            if (n < 0) { // EOF
2158                break;
2159            }
2160            remain -= n;
2161        }
2162        return toSkip - remain;
2163    }
2164
2165    /**
2166     * Skips bytes from a ReadableByteChannel.
2167     * This implementation guarantees that it will read as many bytes
2168     * as possible before giving up.
2169     *
2170     * @param input ReadableByteChannel to skip
2171     * @param toSkip number of bytes to skip.
2172     * @return number of bytes actually skipped.
2173     * @throws IOException              if there is a problem reading the ReadableByteChannel
2174     * @throws IllegalArgumentException if toSkip is negative
2175     * @since 2.5
2176     */
2177    public static long skip(final ReadableByteChannel input, final long toSkip) throws IOException {
2178        if (toSkip < 0) {
2179            throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
2180        }
2181        final ByteBuffer skipByteBuffer = ByteBuffer.allocate((int) Math.min(toSkip, DEFAULT_BUFFER_SIZE));
2182        long remain = toSkip;
2183        while (remain > 0) {
2184            skipByteBuffer.position(0);
2185            skipByteBuffer.limit((int) Math.min(remain, DEFAULT_BUFFER_SIZE));
2186            final int n = input.read(skipByteBuffer);
2187            if (n == EOF) {
2188                break;
2189            }
2190            remain -= n;
2191        }
2192        return toSkip - remain;
2193    }
2194
2195    /**
2196     * Skips characters from an input character stream.
2197     * This implementation guarantees that it will read as many characters
2198     * as possible before giving up; this may not always be the case for
2199     * skip() implementations in subclasses of {@link Reader}.
2200     * <p>
2201     * Note that the implementation uses {@link Reader#read(char[], int, int)} rather
2202     * than delegating to {@link Reader#skip(long)}.
2203     * This means that the method may be considerably less efficient than using the actual skip implementation,
2204     * this is done to guarantee that the correct number of characters are skipped.
2205     * </p>
2206     *
2207     * @param reader character stream to skip
2208     * @param toSkip number of characters to skip.
2209     * @return number of characters actually skipped.
2210     * @throws IOException              if there is a problem reading the file
2211     * @throws IllegalArgumentException if toSkip is negative
2212     * @see Reader#skip(long)
2213     * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a>
2214     * @since 2.0
2215     */
2216    public static long skip(final Reader reader, final long toSkip) throws IOException {
2217        if (toSkip < 0) {
2218            throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
2219        }
2220        long remain = toSkip;
2221        while (remain > 0) {
2222            // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip()
2223            final char[] charArray = getCharArray();
2224            final long n = reader.read(charArray, 0, (int) Math.min(remain, charArray.length));
2225            if (n < 0) { // EOF
2226                break;
2227            }
2228            remain -= n;
2229        }
2230        return toSkip - remain;
2231    }
2232
2233    /**
2234     * Skips the requested number of bytes or fail if there are not enough left.
2235     * <p>
2236     * This allows for the possibility that {@link InputStream#skip(long)} may
2237     * not skip as many bytes as requested (most likely because of reaching EOF).
2238     * <p>
2239     * Note that the implementation uses {@link #skip(InputStream, long)}.
2240     * This means that the method may be considerably less efficient than using the actual skip implementation,
2241     * this is done to guarantee that the correct number of characters are skipped.
2242     * </p>
2243     *
2244     * @param input stream to skip
2245     * @param toSkip the number of bytes to skip
2246     * @throws IOException              if there is a problem reading the file
2247     * @throws IllegalArgumentException if toSkip is negative
2248     * @throws EOFException             if the number of bytes skipped was incorrect
2249     * @see InputStream#skip(long)
2250     * @since 2.0
2251     */
2252    public static void skipFully(final InputStream input, final long toSkip) throws IOException {
2253        if (toSkip < 0) {
2254            throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip);
2255        }
2256        final long skipped = skip(input, toSkip);
2257        if (skipped != toSkip) {
2258            throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped);
2259        }
2260    }
2261
2262    /**
2263     * Skips the requested number of bytes or fail if there are not enough left.
2264     *
2265     * @param input ReadableByteChannel to skip
2266     * @param toSkip the number of bytes to skip
2267     * @throws IOException              if there is a problem reading the ReadableByteChannel
2268     * @throws IllegalArgumentException if toSkip is negative
2269     * @throws EOFException             if the number of bytes skipped was incorrect
2270     * @since 2.5
2271     */
2272    public static void skipFully(final ReadableByteChannel input, final long toSkip) throws IOException {
2273        if (toSkip < 0) {
2274            throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip);
2275        }
2276        final long skipped = skip(input, toSkip);
2277        if (skipped != toSkip) {
2278            throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped);
2279        }
2280    }
2281
2282    /**
2283     * Skips the requested number of characters or fail if there are not enough left.
2284     * <p>
2285     * This allows for the possibility that {@link Reader#skip(long)} may
2286     * not skip as many characters as requested (most likely because of reaching EOF).
2287     * <p>
2288     * Note that the implementation uses {@link #skip(Reader, long)}.
2289     * This means that the method may be considerably less efficient than using the actual skip implementation,
2290     * this is done to guarantee that the correct number of characters are skipped.
2291     * </p>
2292     *
2293     * @param reader stream to skip
2294     * @param toSkip the number of characters to skip
2295     * @throws IOException              if there is a problem reading the file
2296     * @throws IllegalArgumentException if toSkip is negative
2297     * @throws EOFException             if the number of characters skipped was incorrect
2298     * @see Reader#skip(long)
2299     * @since 2.0
2300     */
2301    public static void skipFully(final Reader reader, final long toSkip) throws IOException {
2302        final long skipped = skip(reader, toSkip);
2303        if (skipped != toSkip) {
2304            throw new EOFException("Chars to skip: " + toSkip + " actual: " + skipped);
2305        }
2306    }
2307
2308    /**
2309     * Fetches entire contents of an {@code InputStream} and represent
2310     * same data as result InputStream.
2311     * <p>
2312     * This method is useful where,
2313     * <ul>
2314     * <li>Source InputStream is slow.</li>
2315     * <li>It has network resources associated, so we cannot keep it open for
2316     * long time.</li>
2317     * <li>It has network timeout associated.</li>
2318     * </ul>
2319     * It can be used in favor of {@link #toByteArray(InputStream)}, since it
2320     * avoids unnecessary allocation and copy of byte[].<br>
2321     * This method buffers the input internally, so there is no need to use a
2322     * {@code BufferedInputStream}.
2323     *
2324     * @param input Stream to be fully buffered.
2325     * @return A fully buffered stream.
2326     * @throws IOException if an I/O error occurs.
2327     * @since 2.0
2328     */
2329    public static InputStream toBufferedInputStream(final InputStream input) throws IOException {
2330        return ByteArrayOutputStream.toBufferedInputStream(input);
2331    }
2332
2333    /**
2334     * Fetches entire contents of an {@code InputStream} and represent
2335     * same data as result InputStream.
2336     * <p>
2337     * This method is useful where,
2338     * <ul>
2339     * <li>Source InputStream is slow.</li>
2340     * <li>It has network resources associated, so we cannot keep it open for
2341     * long time.</li>
2342     * <li>It has network timeout associated.</li>
2343     * </ul>
2344     * It can be used in favor of {@link #toByteArray(InputStream)}, since it
2345     * avoids unnecessary allocation and copy of byte[].<br>
2346     * This method buffers the input internally, so there is no need to use a
2347     * {@code BufferedInputStream}.
2348     *
2349     * @param input Stream to be fully buffered.
2350     * @param size the initial buffer size
2351     * @return A fully buffered stream.
2352     * @throws IOException if an I/O error occurs.
2353     * @since 2.5
2354     */
2355    public static InputStream toBufferedInputStream(final InputStream input, final int size) throws IOException {
2356        return ByteArrayOutputStream.toBufferedInputStream(input, size);
2357    }
2358
2359    /**
2360     * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given
2361     * reader.
2362     *
2363     * @param reader the reader to wrap or return (not null)
2364     * @return the given reader or a new {@link BufferedReader} for the given reader
2365     * @throws NullPointerException if the input parameter is null
2366     * @see #buffer(Reader)
2367     * @since 2.2
2368     */
2369    public static BufferedReader toBufferedReader(final Reader reader) {
2370        return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
2371    }
2372
2373    /**
2374     * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given
2375     * reader.
2376     *
2377     * @param reader the reader to wrap or return (not null)
2378     * @param size the buffer size, if a new BufferedReader is created.
2379     * @return the given reader or a new {@link BufferedReader} for the given reader
2380     * @throws NullPointerException if the input parameter is null
2381     * @see #buffer(Reader)
2382     * @since 2.5
2383     */
2384    public static BufferedReader toBufferedReader(final Reader reader, final int size) {
2385        return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader, size);
2386    }
2387
2388    /**
2389     * Gets the contents of an {@code InputStream} as a {@code byte[]}.
2390     * <p>
2391     * This method buffers the input internally, so there is no need to use a
2392     * {@code BufferedInputStream}.
2393     * </p>
2394     *
2395     * @param inputStream the {@code InputStream} to read.
2396     * @return the requested byte array.
2397     * @throws NullPointerException if the InputStream is {@code null}.
2398     * @throws IOException if an I/O error occurs or reading more than {@link Integer#MAX_VALUE} occurs.
2399     */
2400    public static byte[] toByteArray(final InputStream inputStream) throws IOException {
2401        // We use a ThresholdingOutputStream to avoid reading AND writing more than Integer.MAX_VALUE.
2402        try (final UnsynchronizedByteArrayOutputStream ubaOutput = new UnsynchronizedByteArrayOutputStream();
2403            final ThresholdingOutputStream thresholdOuput = new ThresholdingOutputStream(Integer.MAX_VALUE, os -> {
2404                throw new IllegalArgumentException(
2405                    String.format("Cannot read more than %,d into a byte array", Integer.MAX_VALUE));
2406            }, os -> ubaOutput)) {
2407            copy(inputStream, thresholdOuput);
2408            return ubaOutput.toByteArray();
2409        }
2410    }
2411
2412    /**
2413     * Gets the contents of an {@code InputStream} as a {@code byte[]}. Use this method instead of
2414     * {@code toByteArray(InputStream)} when {@code InputStream} size is known
2415     *
2416     * @param input the {@code InputStream} to read.
2417     * @param size the size of {@code InputStream}.
2418     * @return the requested byte array.
2419     * @throws IOException if an I/O error occurs or {@code InputStream} size differ from parameter size.
2420     * @throws IllegalArgumentException if size is less than zero.
2421     * @since 2.1
2422     */
2423    public static byte[] toByteArray(final InputStream input, final int size) throws IOException {
2424
2425        if (size < 0) {
2426            throw new IllegalArgumentException("Size must be equal or greater than zero: " + size);
2427        }
2428
2429        if (size == 0) {
2430            return EMPTY_BYTE_ARRAY;
2431        }
2432
2433        final byte[] data = IOUtils.byteArray(size);
2434        int offset = 0;
2435        int read;
2436
2437        while (offset < size && (read = input.read(data, offset, size - offset)) != EOF) {
2438            offset += read;
2439        }
2440
2441        if (offset != size) {
2442            throw new IOException("Unexpected read size, current: " + offset + ", expected: " + size);
2443        }
2444
2445        return data;
2446    }
2447
2448    /**
2449     * Gets contents of an {@code InputStream} as a {@code byte[]}.
2450     * Use this method instead of {@code toByteArray(InputStream)}
2451     * when {@code InputStream} size is known.
2452     * <b>NOTE:</b> the method checks that the length can safely be cast to an int without truncation
2453     * before using {@link IOUtils#toByteArray(java.io.InputStream, int)} to read into the byte array.
2454     * (Arrays can have no more than Integer.MAX_VALUE entries anyway)
2455     *
2456     * @param input the {@code InputStream} to read from
2457     * @param size the size of {@code InputStream}
2458     * @return the requested byte array
2459     * @throws IOException              if an I/O error occurs or {@code InputStream} size differ from parameter
2460     * size
2461     * @throws IllegalArgumentException if size is less than zero or size is greater than Integer.MAX_VALUE
2462     * @see IOUtils#toByteArray(java.io.InputStream, int)
2463     * @since 2.1
2464     */
2465    public static byte[] toByteArray(final InputStream input, final long size) throws IOException {
2466
2467        if (size > Integer.MAX_VALUE) {
2468            throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size);
2469        }
2470
2471        return toByteArray(input, (int) size);
2472    }
2473
2474    /**
2475     * Gets the contents of a {@code Reader} as a {@code byte[]}
2476     * using the default character encoding of the platform.
2477     * <p>
2478     * This method buffers the input internally, so there is no need to use a
2479     * {@code BufferedReader}.
2480     *
2481     * @param reader the {@code Reader} to read from
2482     * @return the requested byte array
2483     * @throws NullPointerException if the input is null
2484     * @throws IOException          if an I/O error occurs
2485     * @deprecated 2.5 use {@link #toByteArray(Reader, Charset)} instead
2486     */
2487    @Deprecated
2488    public static byte[] toByteArray(final Reader reader) throws IOException {
2489        return toByteArray(reader, Charset.defaultCharset());
2490    }
2491
2492    /**
2493     * Gets the contents of a {@code Reader} as a {@code byte[]}
2494     * using the specified character encoding.
2495     * <p>
2496     * This method buffers the input internally, so there is no need to use a
2497     * {@code BufferedReader}.
2498     *
2499     * @param reader the {@code Reader} to read from
2500     * @param charset the charset to use, null means platform default
2501     * @return the requested byte array
2502     * @throws NullPointerException if the input is null
2503     * @throws IOException          if an I/O error occurs
2504     * @since 2.3
2505     */
2506    public static byte[] toByteArray(final Reader reader, final Charset charset) throws IOException {
2507        try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) {
2508            copy(reader, output, charset);
2509            return output.toByteArray();
2510        }
2511    }
2512
2513    /**
2514     * Gets the contents of a {@code Reader} as a {@code byte[]}
2515     * using the specified character encoding.
2516     * <p>
2517     * Character encoding names can be found at
2518     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
2519     * <p>
2520     * This method buffers the input internally, so there is no need to use a
2521     * {@code BufferedReader}.
2522     *
2523     * @param reader the {@code Reader} to read from
2524     * @param charsetName the name of the requested charset, null means platform default
2525     * @return the requested byte array
2526     * @throws NullPointerException                         if the input is null
2527     * @throws IOException                                  if an I/O error occurs
2528     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
2529     *                                                      .UnsupportedEncodingException} in version 2.2 if the
2530     *                                                      encoding is not supported.
2531     * @since 1.1
2532     */
2533    public static byte[] toByteArray(final Reader reader, final String charsetName) throws IOException {
2534        return toByteArray(reader, Charsets.toCharset(charsetName));
2535    }
2536
2537    /**
2538     * Gets the contents of a {@code String} as a {@code byte[]}
2539     * using the default character encoding of the platform.
2540     * <p>
2541     * This is the same as {@link String#getBytes()}.
2542     *
2543     * @param input the {@code String} to convert
2544     * @return the requested byte array
2545     * @throws NullPointerException if the input is null
2546     * @throws IOException Never thrown.
2547     * @deprecated 2.5 Use {@link String#getBytes()} instead
2548     */
2549    @Deprecated
2550    public static byte[] toByteArray(final String input) throws IOException {
2551        // make explicit the use of the default charset
2552        return input.getBytes(Charset.defaultCharset());
2553    }
2554
2555    /**
2556     * Gets the contents of a {@code URI} as a {@code byte[]}.
2557     *
2558     * @param uri the {@code URI} to read
2559     * @return the requested byte array
2560     * @throws NullPointerException if the uri is null
2561     * @throws IOException          if an I/O exception occurs
2562     * @since 2.4
2563     */
2564    public static byte[] toByteArray(final URI uri) throws IOException {
2565        return IOUtils.toByteArray(uri.toURL());
2566    }
2567
2568    /**
2569     * Gets the contents of a {@code URL} as a {@code byte[]}.
2570     *
2571     * @param url the {@code URL} to read
2572     * @return the requested byte array
2573     * @throws NullPointerException if the input is null
2574     * @throws IOException          if an I/O exception occurs
2575     * @since 2.4
2576     */
2577    public static byte[] toByteArray(final URL url) throws IOException {
2578        final URLConnection conn = url.openConnection();
2579        try {
2580            return IOUtils.toByteArray(conn);
2581        } finally {
2582            close(conn);
2583        }
2584    }
2585
2586    /**
2587     * Gets the contents of a {@code URLConnection} as a {@code byte[]}.
2588     *
2589     * @param urlConn the {@code URLConnection} to read.
2590     * @return the requested byte array.
2591     * @throws NullPointerException if the urlConn is null.
2592     * @throws IOException if an I/O exception occurs.
2593     * @since 2.4
2594     */
2595    public static byte[] toByteArray(final URLConnection urlConn) throws IOException {
2596        try (InputStream inputStream = urlConn.getInputStream()) {
2597            return IOUtils.toByteArray(inputStream);
2598        }
2599    }
2600
2601    /**
2602     * Gets the contents of an {@code InputStream} as a character array
2603     * using the default character encoding of the platform.
2604     * <p>
2605     * This method buffers the input internally, so there is no need to use a
2606     * {@code BufferedInputStream}.
2607     *
2608     * @param inputStream the {@code InputStream} to read from
2609     * @return the requested character array
2610     * @throws NullPointerException if the input is null
2611     * @throws IOException          if an I/O error occurs
2612     * @since 1.1
2613     * @deprecated 2.5 use {@link #toCharArray(InputStream, Charset)} instead
2614     */
2615    @Deprecated
2616    public static char[] toCharArray(final InputStream inputStream) throws IOException {
2617        return toCharArray(inputStream, Charset.defaultCharset());
2618    }
2619
2620    /**
2621     * Gets the contents of an {@code InputStream} as a character array
2622     * using the specified character encoding.
2623     * <p>
2624     * This method buffers the input internally, so there is no need to use a
2625     * {@code BufferedInputStream}.
2626     *
2627     * @param inputStream the {@code InputStream} to read from
2628     * @param charset the charset to use, null means platform default
2629     * @return the requested character array
2630     * @throws NullPointerException if the input is null
2631     * @throws IOException          if an I/O error occurs
2632     * @since 2.3
2633     */
2634    public static char[] toCharArray(final InputStream inputStream, final Charset charset)
2635            throws IOException {
2636        final CharArrayWriter writer = new CharArrayWriter();
2637        copy(inputStream, writer, charset);
2638        return writer.toCharArray();
2639    }
2640
2641    /**
2642     * Gets the contents of an {@code InputStream} as a character array
2643     * using the specified character encoding.
2644     * <p>
2645     * Character encoding names can be found at
2646     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
2647     * <p>
2648     * This method buffers the input internally, so there is no need to use a
2649     * {@code BufferedInputStream}.
2650     *
2651     * @param inputStream the {@code InputStream} to read from
2652     * @param charsetName the name of the requested charset, null means platform default
2653     * @return the requested character array
2654     * @throws NullPointerException                         if the input is null
2655     * @throws IOException                                  if an I/O error occurs
2656     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
2657     *                                                      .UnsupportedEncodingException} in version 2.2 if the
2658     *                                                      encoding is not supported.
2659     * @since 1.1
2660     */
2661    public static char[] toCharArray(final InputStream inputStream, final String charsetName) throws IOException {
2662        return toCharArray(inputStream, Charsets.toCharset(charsetName));
2663    }
2664
2665    /**
2666     * Gets the contents of a {@code Reader} as a character array.
2667     * <p>
2668     * This method buffers the input internally, so there is no need to use a
2669     * {@code BufferedReader}.
2670     *
2671     * @param reader the {@code Reader} to read from
2672     * @return the requested character array
2673     * @throws NullPointerException if the input is null
2674     * @throws IOException          if an I/O error occurs
2675     * @since 1.1
2676     */
2677    public static char[] toCharArray(final Reader reader) throws IOException {
2678        final CharArrayWriter sw = new CharArrayWriter();
2679        copy(reader, sw);
2680        return sw.toCharArray();
2681    }
2682
2683    /**
2684     * Converts the specified CharSequence to an input stream, encoded as bytes
2685     * using the default character encoding of the platform.
2686     *
2687     * @param input the CharSequence to convert
2688     * @return an input stream
2689     * @since 2.0
2690     * @deprecated 2.5 use {@link #toInputStream(CharSequence, Charset)} instead
2691     */
2692    @Deprecated
2693    public static InputStream toInputStream(final CharSequence input) {
2694        return toInputStream(input, Charset.defaultCharset());
2695    }
2696
2697    /**
2698     * Converts the specified CharSequence to an input stream, encoded as bytes
2699     * using the specified character encoding.
2700     *
2701     * @param input the CharSequence to convert
2702     * @param charset the charset to use, null means platform default
2703     * @return an input stream
2704     * @since 2.3
2705     */
2706    public static InputStream toInputStream(final CharSequence input, final Charset charset) {
2707        return toInputStream(input.toString(), charset);
2708    }
2709
2710    /**
2711     * Converts the specified CharSequence to an input stream, encoded as bytes
2712     * using the specified character encoding.
2713     * <p>
2714     * Character encoding names can be found at
2715     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
2716     *
2717     * @param input the CharSequence to convert
2718     * @param charsetName the name of the requested charset, null means platform default
2719     * @return an input stream
2720     * @throws IOException Never thrown.
2721     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
2722     *                                                      .UnsupportedEncodingException} in version 2.2 if the
2723     *                                                      encoding is not supported.
2724     * @since 2.0
2725     */
2726    public static InputStream toInputStream(final CharSequence input, final String charsetName) throws IOException {
2727        return toInputStream(input, Charsets.toCharset(charsetName));
2728    }
2729
2730    /**
2731     * Converts the specified string to an input stream, encoded as bytes
2732     * using the default character encoding of the platform.
2733     *
2734     * @param input the string to convert
2735     * @return an input stream
2736     * @since 1.1
2737     * @deprecated 2.5 use {@link #toInputStream(String, Charset)} instead
2738     */
2739    @Deprecated
2740    public static InputStream toInputStream(final String input) {
2741        return toInputStream(input, Charset.defaultCharset());
2742    }
2743
2744    /**
2745     * Converts the specified string to an input stream, encoded as bytes
2746     * using the specified character encoding.
2747     *
2748     * @param input the string to convert
2749     * @param charset the charset to use, null means platform default
2750     * @return an input stream
2751     * @since 2.3
2752     */
2753    public static InputStream toInputStream(final String input, final Charset charset) {
2754        return new ByteArrayInputStream(input.getBytes(Charsets.toCharset(charset)));
2755    }
2756
2757    /**
2758     * Converts the specified string to an input stream, encoded as bytes
2759     * using the specified character encoding.
2760     * <p>
2761     * Character encoding names can be found at
2762     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
2763     *
2764     * @param input the string to convert
2765     * @param charsetName the name of the requested charset, null means platform default
2766     * @return an input stream
2767     * @throws IOException Never thrown.
2768     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
2769     *                                                      .UnsupportedEncodingException} in version 2.2 if the
2770     *                                                      encoding is not supported.
2771     * @since 1.1
2772     */
2773    public static InputStream toInputStream(final String input, final String charsetName) throws IOException {
2774        final byte[] bytes = input.getBytes(Charsets.toCharset(charsetName));
2775        return new ByteArrayInputStream(bytes);
2776    }
2777
2778    /**
2779     * Gets the contents of a {@code byte[]} as a String
2780     * using the default character encoding of the platform.
2781     *
2782     * @param input the byte array to read from
2783     * @return the requested String
2784     * @throws NullPointerException if the input is null
2785     * @throws IOException Never thrown.
2786     * @deprecated 2.5 Use {@link String#String(byte[])} instead
2787     */
2788    @Deprecated
2789    public static String toString(final byte[] input) throws IOException {
2790        // make explicit the use of the default charset
2791        return new String(input, Charset.defaultCharset());
2792    }
2793
2794    /**
2795     * Gets the contents of a {@code byte[]} as a String
2796     * using the specified character encoding.
2797     * <p>
2798     * Character encoding names can be found at
2799     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
2800     *
2801     * @param input the byte array to read from
2802     * @param charsetName the name of the requested charset, null means platform default
2803     * @return the requested String
2804     * @throws NullPointerException if the input is null
2805     * @throws IOException Never thrown.
2806     */
2807    public static String toString(final byte[] input, final String charsetName) throws IOException {
2808        return new String(input, Charsets.toCharset(charsetName));
2809    }
2810
2811    /**
2812     * Gets the contents of an {@code InputStream} as a String
2813     * using the default character encoding of the platform.
2814     * <p>
2815     * This method buffers the input internally, so there is no need to use a
2816     * {@code BufferedInputStream}.
2817     *
2818     * @param input the {@code InputStream} to read from
2819     * @return the requested String
2820     * @throws NullPointerException if the input is null
2821     * @throws IOException          if an I/O error occurs
2822     * @deprecated 2.5 use {@link #toString(InputStream, Charset)} instead
2823     */
2824    @Deprecated
2825    public static String toString(final InputStream input) throws IOException {
2826        return toString(input, Charset.defaultCharset());
2827    }
2828
2829    /**
2830     * Gets the contents of an {@code InputStream} as a String
2831     * using the specified character encoding.
2832     * <p>
2833     * This method buffers the input internally, so there is no need to use a
2834     * {@code BufferedInputStream}.
2835     * </p>
2836     *
2837     * @param input the {@code InputStream} to read from
2838     * @param charset the charset to use, null means platform default
2839     * @return the requested String
2840     * @throws NullPointerException if the input is null
2841     * @throws IOException          if an I/O error occurs
2842     * @since 2.3
2843     */
2844    public static String toString(final InputStream input, final Charset charset) throws IOException {
2845        try (final StringBuilderWriter sw = new StringBuilderWriter()) {
2846            copy(input, sw, charset);
2847            return sw.toString();
2848        }
2849    }
2850
2851    /**
2852     * Gets the contents of an {@code InputStream} as a String
2853     * using the specified character encoding.
2854     * <p>
2855     * Character encoding names can be found at
2856     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
2857     * <p>
2858     * This method buffers the input internally, so there is no need to use a
2859     * {@code BufferedInputStream}.
2860     *
2861     * @param input the {@code InputStream} to read from
2862     * @param charsetName the name of the requested charset, null means platform default
2863     * @return the requested String
2864     * @throws NullPointerException                         if the input is null
2865     * @throws IOException                                  if an I/O error occurs
2866     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
2867     *                                                      .UnsupportedEncodingException} in version 2.2 if the
2868     *                                                      encoding is not supported.
2869     */
2870    public static String toString(final InputStream input, final String charsetName)
2871            throws IOException {
2872        return toString(input, Charsets.toCharset(charsetName));
2873    }
2874
2875    /**
2876     * Gets the contents of a {@code Reader} as a String.
2877     * <p>
2878     * This method buffers the input internally, so there is no need to use a
2879     * {@code BufferedReader}.
2880     *
2881     * @param reader the {@code Reader} to read from
2882     * @return the requested String
2883     * @throws NullPointerException if the input is null
2884     * @throws IOException          if an I/O error occurs
2885     */
2886    public static String toString(final Reader reader) throws IOException {
2887        try (final StringBuilderWriter sw = new StringBuilderWriter()) {
2888            copy(reader, sw);
2889            return sw.toString();
2890        }
2891    }
2892
2893    /**
2894     * Gets the contents at the given URI.
2895     *
2896     * @param uri The URI source.
2897     * @return The contents of the URL as a String.
2898     * @throws IOException if an I/O exception occurs.
2899     * @since 2.1
2900     * @deprecated 2.5 use {@link #toString(URI, Charset)} instead
2901     */
2902    @Deprecated
2903    public static String toString(final URI uri) throws IOException {
2904        return toString(uri, Charset.defaultCharset());
2905    }
2906
2907    /**
2908     * Gets the contents at the given URI.
2909     *
2910     * @param uri The URI source.
2911     * @param encoding The encoding name for the URL contents.
2912     * @return The contents of the URL as a String.
2913     * @throws IOException if an I/O exception occurs.
2914     * @since 2.3.
2915     */
2916    public static String toString(final URI uri, final Charset encoding) throws IOException {
2917        return toString(uri.toURL(), Charsets.toCharset(encoding));
2918    }
2919
2920    /**
2921     * Gets the contents at the given URI.
2922     *
2923     * @param uri The URI source.
2924     * @param charsetName The encoding name for the URL contents.
2925     * @return The contents of the URL as a String.
2926     * @throws IOException                                  if an I/O exception occurs.
2927     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
2928     *                                                      .UnsupportedEncodingException} in version 2.2 if the
2929     *                                                      encoding is not supported.
2930     * @since 2.1
2931     */
2932    public static String toString(final URI uri, final String charsetName) throws IOException {
2933        return toString(uri, Charsets.toCharset(charsetName));
2934    }
2935
2936    /**
2937     * Gets the contents at the given URL.
2938     *
2939     * @param url The URL source.
2940     * @return The contents of the URL as a String.
2941     * @throws IOException if an I/O exception occurs.
2942     * @since 2.1
2943     * @deprecated 2.5 use {@link #toString(URL, Charset)} instead
2944     */
2945    @Deprecated
2946    public static String toString(final URL url) throws IOException {
2947        return toString(url, Charset.defaultCharset());
2948    }
2949
2950    /**
2951     * Gets the contents at the given URL.
2952     *
2953     * @param url The URL source.
2954     * @param encoding The encoding name for the URL contents.
2955     * @return The contents of the URL as a String.
2956     * @throws IOException if an I/O exception occurs.
2957     * @since 2.3
2958     */
2959    public static String toString(final URL url, final Charset encoding) throws IOException {
2960        try (InputStream inputStream = url.openStream()) {
2961            return toString(inputStream, encoding);
2962        }
2963    }
2964
2965    /**
2966     * Gets the contents at the given URL.
2967     *
2968     * @param url The URL source.
2969     * @param charsetName The encoding name for the URL contents.
2970     * @return The contents of the URL as a String.
2971     * @throws IOException                                  if an I/O exception occurs.
2972     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
2973     *                                                      .UnsupportedEncodingException} in version 2.2 if the
2974     *                                                      encoding is not supported.
2975     * @since 2.1
2976     */
2977    public static String toString(final URL url, final String charsetName) throws IOException {
2978        return toString(url, Charsets.toCharset(charsetName));
2979    }
2980
2981    /**
2982     * Writes bytes from a {@code byte[]} to an {@code OutputStream}.
2983     *
2984     * @param data the byte array to write, do not modify during output,
2985     * null ignored
2986     * @param output the {@code OutputStream} to write to
2987     * @throws NullPointerException if output is null
2988     * @throws IOException          if an I/O error occurs
2989     * @since 1.1
2990     */
2991    public static void write(final byte[] data, final OutputStream output)
2992            throws IOException {
2993        if (data != null) {
2994            output.write(data);
2995        }
2996    }
2997
2998    /**
2999     * Writes bytes from a {@code byte[]} to chars on a {@code Writer}
3000     * using the default character encoding of the platform.
3001     * <p>
3002     * This method uses {@link String#String(byte[])}.
3003     *
3004     * @param data the byte array to write, do not modify during output,
3005     * null ignored
3006     * @param writer the {@code Writer} to write to
3007     * @throws NullPointerException if output is null
3008     * @throws IOException          if an I/O error occurs
3009     * @since 1.1
3010     * @deprecated 2.5 use {@link #write(byte[], Writer, Charset)} instead
3011     */
3012    @Deprecated
3013    public static void write(final byte[] data, final Writer writer) throws IOException {
3014        write(data, writer, Charset.defaultCharset());
3015    }
3016
3017    /**
3018     * Writes bytes from a {@code byte[]} to chars on a {@code Writer}
3019     * using the specified character encoding.
3020     * <p>
3021     * This method uses {@link String#String(byte[], String)}.
3022     *
3023     * @param data the byte array to write, do not modify during output,
3024     * null ignored
3025     * @param writer the {@code Writer} to write to
3026     * @param charset the charset to use, null means platform default
3027     * @throws NullPointerException if output is null
3028     * @throws IOException          if an I/O error occurs
3029     * @since 2.3
3030     */
3031    public static void write(final byte[] data, final Writer writer, final Charset charset) throws IOException {
3032        if (data != null) {
3033            writer.write(new String(data, Charsets.toCharset(charset)));
3034        }
3035    }
3036
3037    /**
3038     * Writes bytes from a {@code byte[]} to chars on a {@code Writer}
3039     * using the specified character encoding.
3040     * <p>
3041     * Character encoding names can be found at
3042     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
3043     * <p>
3044     * This method uses {@link String#String(byte[], String)}.
3045     *
3046     * @param data the byte array to write, do not modify during output,
3047     * null ignored
3048     * @param writer the {@code Writer} to write to
3049     * @param charsetName the name of the requested charset, null means platform default
3050     * @throws NullPointerException                         if output is null
3051     * @throws IOException                                  if an I/O error occurs
3052     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
3053     *                                                      .UnsupportedEncodingException} in version 2.2 if the
3054     *                                                      encoding is not supported.
3055     * @since 1.1
3056     */
3057    public static void write(final byte[] data, final Writer writer, final String charsetName) throws IOException {
3058        write(data, writer, Charsets.toCharset(charsetName));
3059    }
3060
3061    /**
3062     * Writes chars from a {@code char[]} to bytes on an
3063     * {@code OutputStream}.
3064     * <p>
3065     * This method uses {@link String#String(char[])} and
3066     * {@link String#getBytes()}.
3067     *
3068     * @param data the char array to write, do not modify during output,
3069     * null ignored
3070     * @param output the {@code OutputStream} to write to
3071     * @throws NullPointerException if output is null
3072     * @throws IOException          if an I/O error occurs
3073     * @since 1.1
3074     * @deprecated 2.5 use {@link #write(char[], OutputStream, Charset)} instead
3075     */
3076    @Deprecated
3077    public static void write(final char[] data, final OutputStream output)
3078            throws IOException {
3079        write(data, output, Charset.defaultCharset());
3080    }
3081
3082    /**
3083     * Writes chars from a {@code char[]} to bytes on an
3084     * {@code OutputStream} using the specified character encoding.
3085     * <p>
3086     * This method uses {@link String#String(char[])} and
3087     * {@link String#getBytes(String)}.
3088     *
3089     * @param data the char array to write, do not modify during output,
3090     * null ignored
3091     * @param output the {@code OutputStream} to write to
3092     * @param charset the charset to use, null means platform default
3093     * @throws NullPointerException if output is null
3094     * @throws IOException          if an I/O error occurs
3095     * @since 2.3
3096     */
3097    public static void write(final char[] data, final OutputStream output, final Charset charset) throws IOException {
3098        if (data != null) {
3099            output.write(new String(data).getBytes(Charsets.toCharset(charset)));
3100        }
3101    }
3102
3103    /**
3104     * Writes chars from a {@code char[]} to bytes on an
3105     * {@code OutputStream} using the specified character encoding.
3106     * <p>
3107     * Character encoding names can be found at
3108     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
3109     * <p>
3110     * This method uses {@link String#String(char[])} and
3111     * {@link String#getBytes(String)}.
3112     *
3113     * @param data the char array to write, do not modify during output,
3114     * null ignored
3115     * @param output the {@code OutputStream} to write to
3116     * @param charsetName the name of the requested charset, null means platform default
3117     * @throws NullPointerException                         if output is null
3118     * @throws IOException                                  if an I/O error occurs
3119     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
3120     * .UnsupportedEncodingException} in version 2.2 if the encoding is not supported.
3121     * @since 1.1
3122     */
3123    public static void write(final char[] data, final OutputStream output, final String charsetName)
3124            throws IOException {
3125        write(data, output, Charsets.toCharset(charsetName));
3126    }
3127
3128    /**
3129     * Writes chars from a {@code char[]} to a {@code Writer}
3130     *
3131     * @param data the char array to write, do not modify during output,
3132     * null ignored
3133     * @param writer the {@code Writer} to write to
3134     * @throws NullPointerException if output is null
3135     * @throws IOException          if an I/O error occurs
3136     * @since 1.1
3137     */
3138    public static void write(final char[] data, final Writer writer) throws IOException {
3139        if (data != null) {
3140            writer.write(data);
3141        }
3142    }
3143
3144    /**
3145     * Writes chars from a {@code CharSequence} to bytes on an
3146     * {@code OutputStream} using the default character encoding of the
3147     * platform.
3148     * <p>
3149     * This method uses {@link String#getBytes()}.
3150     *
3151     * @param data the {@code CharSequence} to write, null ignored
3152     * @param output the {@code OutputStream} to write to
3153     * @throws NullPointerException if output is null
3154     * @throws IOException          if an I/O error occurs
3155     * @since 2.0
3156     * @deprecated 2.5 use {@link #write(CharSequence, OutputStream, Charset)} instead
3157     */
3158    @Deprecated
3159    public static void write(final CharSequence data, final OutputStream output)
3160            throws IOException {
3161        write(data, output, Charset.defaultCharset());
3162    }
3163
3164    /**
3165     * Writes chars from a {@code CharSequence} to bytes on an
3166     * {@code OutputStream} using the specified character encoding.
3167     * <p>
3168     * This method uses {@link String#getBytes(String)}.
3169     *
3170     * @param data the {@code CharSequence} to write, null ignored
3171     * @param output the {@code OutputStream} to write to
3172     * @param charset the charset to use, null means platform default
3173     * @throws NullPointerException if output is null
3174     * @throws IOException          if an I/O error occurs
3175     * @since 2.3
3176     */
3177    public static void write(final CharSequence data, final OutputStream output, final Charset charset)
3178            throws IOException {
3179        if (data != null) {
3180            write(data.toString(), output, charset);
3181        }
3182    }
3183
3184    /**
3185     * Writes chars from a {@code CharSequence} to bytes on an
3186     * {@code OutputStream} using the specified character encoding.
3187     * <p>
3188     * Character encoding names can be found at
3189     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
3190     * <p>
3191     * This method uses {@link String#getBytes(String)}.
3192     *
3193     * @param data the {@code CharSequence} to write, null ignored
3194     * @param output the {@code OutputStream} to write to
3195     * @param charsetName the name of the requested charset, null means platform default
3196     * @throws NullPointerException        if output is null
3197     * @throws IOException                 if an I/O error occurs
3198     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
3199     * .UnsupportedEncodingException} in version 2.2 if the encoding is not supported.
3200     * @since 2.0
3201     */
3202    public static void write(final CharSequence data, final OutputStream output, final String charsetName)
3203            throws IOException {
3204        write(data, output, Charsets.toCharset(charsetName));
3205    }
3206
3207    /**
3208     * Writes chars from a {@code CharSequence} to a {@code Writer}.
3209     *
3210     * @param data the {@code CharSequence} to write, null ignored
3211     * @param writer the {@code Writer} to write to
3212     * @throws NullPointerException if output is null
3213     * @throws IOException          if an I/O error occurs
3214     * @since 2.0
3215     */
3216    public static void write(final CharSequence data, final Writer writer) throws IOException {
3217        if (data != null) {
3218            write(data.toString(), writer);
3219        }
3220    }
3221
3222
3223    /**
3224     * Writes chars from a {@code String} to bytes on an
3225     * {@code OutputStream} using the default character encoding of the
3226     * platform.
3227     * <p>
3228     * This method uses {@link String#getBytes()}.
3229     *
3230     * @param data the {@code String} to write, null ignored
3231     * @param output the {@code OutputStream} to write to
3232     * @throws NullPointerException if output is null
3233     * @throws IOException          if an I/O error occurs
3234     * @since 1.1
3235     * @deprecated 2.5 use {@link #write(String, OutputStream, Charset)} instead
3236     */
3237    @Deprecated
3238    public static void write(final String data, final OutputStream output)
3239            throws IOException {
3240        write(data, output, Charset.defaultCharset());
3241    }
3242
3243    /**
3244     * Writes chars from a {@code String} to bytes on an
3245     * {@code OutputStream} using the specified character encoding.
3246     * <p>
3247     * This method uses {@link String#getBytes(String)}.
3248     *
3249     * @param data the {@code String} to write, null ignored
3250     * @param output the {@code OutputStream} to write to
3251     * @param charset the charset to use, null means platform default
3252     * @throws NullPointerException if output is null
3253     * @throws IOException          if an I/O error occurs
3254     * @since 2.3
3255     */
3256    public static void write(final String data, final OutputStream output, final Charset charset) throws IOException {
3257        if (data != null) {
3258            output.write(data.getBytes(Charsets.toCharset(charset)));
3259        }
3260    }
3261
3262    /**
3263     * Writes chars from a {@code String} to bytes on an
3264     * {@code OutputStream} using the specified character encoding.
3265     * <p>
3266     * Character encoding names can be found at
3267     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
3268     * <p>
3269     * This method uses {@link String#getBytes(String)}.
3270     *
3271     * @param data the {@code String} to write, null ignored
3272     * @param output the {@code OutputStream} to write to
3273     * @param charsetName the name of the requested charset, null means platform default
3274     * @throws NullPointerException        if output is null
3275     * @throws IOException                 if an I/O error occurs
3276     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
3277     * .UnsupportedEncodingException} in version 2.2 if the encoding is not supported.
3278     * @since 1.1
3279     */
3280    public static void write(final String data, final OutputStream output, final String charsetName)
3281            throws IOException {
3282        write(data, output, Charsets.toCharset(charsetName));
3283    }
3284
3285    /**
3286     * Writes chars from a {@code String} to a {@code Writer}.
3287     *
3288     * @param data the {@code String} to write, null ignored
3289     * @param writer the {@code Writer} to write to
3290     * @throws NullPointerException if output is null
3291     * @throws IOException          if an I/O error occurs
3292     * @since 1.1
3293     */
3294    public static void write(final String data, final Writer writer) throws IOException {
3295        if (data != null) {
3296            writer.write(data);
3297        }
3298    }
3299
3300    /**
3301     * Writes chars from a {@code StringBuffer} to bytes on an
3302     * {@code OutputStream} using the default character encoding of the
3303     * platform.
3304     * <p>
3305     * This method uses {@link String#getBytes()}.
3306     *
3307     * @param data the {@code StringBuffer} to write, null ignored
3308     * @param output the {@code OutputStream} to write to
3309     * @throws NullPointerException if output is null
3310     * @throws IOException          if an I/O error occurs
3311     * @since 1.1
3312     * @deprecated replaced by write(CharSequence, OutputStream)
3313     */
3314    @Deprecated
3315    public static void write(final StringBuffer data, final OutputStream output) //NOSONAR
3316            throws IOException {
3317        write(data, output, (String) null);
3318    }
3319
3320    /**
3321     * Writes chars from a {@code StringBuffer} to bytes on an
3322     * {@code OutputStream} using the specified character encoding.
3323     * <p>
3324     * Character encoding names can be found at
3325     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
3326     * <p>
3327     * This method uses {@link String#getBytes(String)}.
3328     *
3329     * @param data the {@code StringBuffer} to write, null ignored
3330     * @param output the {@code OutputStream} to write to
3331     * @param charsetName the name of the requested charset, null means platform default
3332     * @throws NullPointerException        if output is null
3333     * @throws IOException                 if an I/O error occurs
3334     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
3335     * .UnsupportedEncodingException} in version 2.2 if the encoding is not supported.
3336     * @since 1.1
3337     * @deprecated replaced by write(CharSequence, OutputStream, String)
3338     */
3339    @Deprecated
3340    public static void write(final StringBuffer data, final OutputStream output, final String charsetName) //NOSONAR
3341            throws IOException {
3342        if (data != null) {
3343            output.write(data.toString().getBytes(Charsets.toCharset(charsetName)));
3344        }
3345    }
3346
3347    /**
3348     * Writes chars from a {@code StringBuffer} to a {@code Writer}.
3349     *
3350     * @param data the {@code StringBuffer} to write, null ignored
3351     * @param writer the {@code Writer} to write to
3352     * @throws NullPointerException if output is null
3353     * @throws IOException          if an I/O error occurs
3354     * @since 1.1
3355     * @deprecated replaced by write(CharSequence, Writer)
3356     */
3357    @Deprecated
3358    public static void write(final StringBuffer data, final Writer writer) //NOSONAR
3359            throws IOException {
3360        if (data != null) {
3361            writer.write(data.toString());
3362        }
3363    }
3364
3365    /**
3366     * Writes bytes from a {@code byte[]} to an {@code OutputStream} using chunked writes.
3367     * This is intended for writing very large byte arrays which might otherwise cause excessive
3368     * memory usage if the native code has to allocate a copy.
3369     *
3370     * @param data the byte array to write, do not modify during output,
3371     * null ignored
3372     * @param output the {@code OutputStream} to write to
3373     * @throws NullPointerException if output is null
3374     * @throws IOException          if an I/O error occurs
3375     * @since 2.5
3376     */
3377    public static void writeChunked(final byte[] data, final OutputStream output)
3378            throws IOException {
3379        if (data != null) {
3380            int bytes = data.length;
3381            int offset = 0;
3382            while (bytes > 0) {
3383                final int chunk = Math.min(bytes, DEFAULT_BUFFER_SIZE);
3384                output.write(data, offset, chunk);
3385                bytes -= chunk;
3386                offset += chunk;
3387            }
3388        }
3389    }
3390
3391    /**
3392     * Writes chars from a {@code char[]} to a {@code Writer} using chunked writes.
3393     * This is intended for writing very large byte arrays which might otherwise cause excessive
3394     * memory usage if the native code has to allocate a copy.
3395     *
3396     * @param data the char array to write, do not modify during output,
3397     * null ignored
3398     * @param writer the {@code Writer} to write to
3399     * @throws NullPointerException if output is null
3400     * @throws IOException          if an I/O error occurs
3401     * @since 2.5
3402     */
3403    public static void writeChunked(final char[] data, final Writer writer) throws IOException {
3404        if (data != null) {
3405            int bytes = data.length;
3406            int offset = 0;
3407            while (bytes > 0) {
3408                final int chunk = Math.min(bytes, DEFAULT_BUFFER_SIZE);
3409                writer.write(data, offset, chunk);
3410                bytes -= chunk;
3411                offset += chunk;
3412            }
3413        }
3414    }
3415
3416    /**
3417     * Writes the {@code toString()} value of each item in a collection to
3418     * an {@code OutputStream} line by line, using the default character
3419     * encoding of the platform and the specified line ending.
3420     *
3421     * @param lines the lines to write, null entries produce blank lines
3422     * @param lineEnding the line separator to use, null is system default
3423     * @param output the {@code OutputStream} to write to, not null, not closed
3424     * @throws NullPointerException if the output is null
3425     * @throws IOException          if an I/O error occurs
3426     * @since 1.1
3427     * @deprecated 2.5 use {@link #writeLines(Collection, String, OutputStream, Charset)} instead
3428     */
3429    @Deprecated
3430    public static void writeLines(final Collection<?> lines, final String lineEnding,
3431                                  final OutputStream output) throws IOException {
3432        writeLines(lines, lineEnding, output, Charset.defaultCharset());
3433    }
3434
3435    /**
3436     * Writes the {@code toString()} value of each item in a collection to
3437     * an {@code OutputStream} line by line, using the specified character
3438     * encoding and the specified line ending.
3439     *
3440     * @param lines the lines to write, null entries produce blank lines
3441     * @param lineEnding the line separator to use, null is system default
3442     * @param output the {@code OutputStream} to write to, not null, not closed
3443     * @param charset the charset to use, null means platform default
3444     * @throws NullPointerException if the output is null
3445     * @throws IOException          if an I/O error occurs
3446     * @since 2.3
3447     */
3448    public static void writeLines(final Collection<?> lines, String lineEnding, final OutputStream output,
3449                                  final Charset charset) throws IOException {
3450        if (lines == null) {
3451            return;
3452        }
3453        if (lineEnding == null) {
3454            lineEnding = System.lineSeparator();
3455        }
3456        final Charset cs = Charsets.toCharset(charset);
3457        for (final Object line : lines) {
3458            if (line != null) {
3459                output.write(line.toString().getBytes(cs));
3460            }
3461            output.write(lineEnding.getBytes(cs));
3462        }
3463    }
3464
3465    /**
3466     * Writes the {@code toString()} value of each item in a collection to
3467     * an {@code OutputStream} line by line, using the specified character
3468     * encoding and the specified line ending.
3469     * <p>
3470     * Character encoding names can be found at
3471     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
3472     *
3473     * @param lines the lines to write, null entries produce blank lines
3474     * @param lineEnding the line separator to use, null is system default
3475     * @param output the {@code OutputStream} to write to, not null, not closed
3476     * @param charsetName the name of the requested charset, null means platform default
3477     * @throws NullPointerException                         if the output is null
3478     * @throws IOException                                  if an I/O error occurs
3479     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
3480     *                                                      .UnsupportedEncodingException} in version 2.2 if the
3481     *                                                      encoding is not supported.
3482     * @since 1.1
3483     */
3484    public static void writeLines(final Collection<?> lines, final String lineEnding,
3485                                  final OutputStream output, final String charsetName) throws IOException {
3486        writeLines(lines, lineEnding, output, Charsets.toCharset(charsetName));
3487    }
3488
3489    /**
3490     * Writes the {@code toString()} value of each item in a collection to
3491     * a {@code Writer} line by line, using the specified line ending.
3492     *
3493     * @param lines the lines to write, null entries produce blank lines
3494     * @param lineEnding the line separator to use, null is system default
3495     * @param writer the {@code Writer} to write to, not null, not closed
3496     * @throws NullPointerException if the input is null
3497     * @throws IOException          if an I/O error occurs
3498     * @since 1.1
3499     */
3500    public static void writeLines(final Collection<?> lines, String lineEnding,
3501                                  final Writer writer) throws IOException {
3502        if (lines == null) {
3503            return;
3504        }
3505        if (lineEnding == null) {
3506            lineEnding = System.lineSeparator();
3507        }
3508        for (final Object line : lines) {
3509            if (line != null) {
3510                writer.write(line.toString());
3511            }
3512            writer.write(lineEnding);
3513        }
3514    }
3515
3516    /**
3517     * Returns the given Appendable if it is already a {@link Writer}, otherwise creates a Writer wrapper around the
3518     * given Appendable.
3519     *
3520     * @param appendable the Appendable to wrap or return (not null)
3521     * @return  the given Appendable or a Writer wrapper around the given Appendable
3522     * @throws NullPointerException if the input parameter is null
3523     * @since 2.7
3524     */
3525    public static Writer writer(final Appendable appendable) {
3526        Objects.requireNonNull(appendable, "appendable");
3527        if (appendable instanceof Writer) {
3528            return (Writer) appendable;
3529        }
3530        if (appendable instanceof StringBuilder) {
3531            return new StringBuilderWriter((StringBuilder) appendable);
3532        }
3533        return new AppendableWriter<>(appendable);
3534    }
3535
3536    /**
3537     * Instances should NOT be constructed in standard programming.
3538     */
3539    public IOUtils() { //NOSONAR
3540
3541    }
3542
3543}