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.BufferedReader;
021import java.io.ByteArrayInputStream;
022import java.io.CharArrayWriter;
023import java.io.Closeable;
024import java.io.EOFException;
025import java.io.File;
026import java.io.IOException;
027import java.io.InputStream;
028import java.io.InputStreamReader;
029import java.io.OutputStream;
030import java.io.OutputStreamWriter;
031import java.io.PrintWriter;
032import java.io.Reader;
033import java.io.UnsupportedEncodingException;
034import java.io.Writer;
035import java.net.HttpURLConnection;
036import java.net.ServerSocket;
037import java.net.Socket;
038import java.net.URI;
039import java.net.URL;
040import java.net.URLConnection;
041import java.nio.channels.Selector;
042import java.nio.charset.Charset;
043import java.nio.charset.UnsupportedCharsetException;
044import java.util.ArrayList;
045import java.util.Collection;
046import java.util.List;
047
048import org.apache.commons.io.output.ByteArrayOutputStream;
049import org.apache.commons.io.output.StringBuilderWriter;
050
051/**
052 * General IO stream manipulation utilities.
053 * <p>
054 * This class provides static utility methods for input/output operations.
055 * <ul>
056 * <li>closeQuietly - these methods close a stream ignoring nulls and exceptions
057 * <li>toXxx/read - these methods read data from a stream
058 * <li>write - these methods write data to a stream
059 * <li>copy - these methods copy all the data from one stream to another
060 * <li>contentEquals - these methods compare the content of two streams
061 * </ul>
062 * <p>
063 * The byte-to-char methods and char-to-byte methods involve a conversion step.
064 * Two methods are provided in each case, one that uses the platform default
065 * encoding and the other which allows you to specify an encoding. You are
066 * encouraged to always specify an encoding because relying on the platform
067 * default can lead to unexpected results, for example when moving from
068 * development to production.
069 * <p>
070 * All the methods in this class that read a stream are buffered internally.
071 * This means that there is no cause to use a <code>BufferedInputStream</code>
072 * or <code>BufferedReader</code>. The default buffer size of 4K has been shown
073 * to be efficient in tests.
074 * <p>
075 * Wherever possible, the methods in this class do <em>not</em> flush or close
076 * the stream. This is to avoid making non-portable assumptions about the
077 * streams' origin and further use. Thus the caller is still responsible for
078 * closing streams after use.
079 * <p>
080 * Origin of code: Excalibur.
081 *
082 * @version $Id: IOUtils.java 1326636 2012-04-16 14:54:53Z ggregory $
083 */
084public class IOUtils {
085    // NOTE: This class is focussed on InputStream, OutputStream, Reader and
086    // Writer. Each method should take at least one of these as a parameter,
087    // or return one of them.
088
089    private static final int EOF = -1;
090    /**
091     * The Unix directory separator character.
092     */
093    public static final char DIR_SEPARATOR_UNIX = '/';
094    /**
095     * The Windows directory separator character.
096     */
097    public static final char DIR_SEPARATOR_WINDOWS = '\\';
098    /**
099     * The system directory separator character.
100     */
101    public static final char DIR_SEPARATOR = File.separatorChar;
102    /**
103     * The Unix line separator string.
104     */
105    public static final String LINE_SEPARATOR_UNIX = "\n";
106    /**
107     * The Windows line separator string.
108     */
109    public static final String LINE_SEPARATOR_WINDOWS = "\r\n";
110    /**
111     * The system line separator string.
112     */
113    public static final String LINE_SEPARATOR;
114    
115    static {
116        // avoid security issues
117        StringBuilderWriter buf = new StringBuilderWriter(4);
118        PrintWriter out = new PrintWriter(buf);
119        out.println();
120        LINE_SEPARATOR = buf.toString();
121        out.close();
122    }
123
124    /**
125     * The default buffer size ({@value}) to use for 
126     * {@link #copyLarge(InputStream, OutputStream)}
127     * and
128     * {@link #copyLarge(Reader, Writer)}
129     */
130    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
131
132    /**
133     * The default buffer size to use for the skip() methods.
134     */
135    private static final int SKIP_BUFFER_SIZE = 2048;
136    
137    // Allocated in the relevant skip method if necessary.
138    /*
139     * N.B. no need to synchronize these because:
140     * - we don't care if the buffer is created multiple times (the data is ignored)
141     * - we always use the same size buffer, so if it it is recreated it will still be OK
142     * (if the buffer size were variable, we would need to synch. to ensure some other thread
143     * did not create a smaller one)
144     */
145    private static char[] SKIP_CHAR_BUFFER;
146    private static byte[] SKIP_BYTE_BUFFER;
147
148    /**
149     * Instances should NOT be constructed in standard programming.
150     */
151    public IOUtils() {
152        super();
153    }
154
155    //-----------------------------------------------------------------------
156    
157    /**
158     * Closes a URLConnection.
159     * 
160     * @param conn the connection to close.
161     * @since 2.4
162     */
163    public static void close(URLConnection conn) {
164        if (conn instanceof HttpURLConnection) {
165            ((HttpURLConnection) conn).disconnect();
166        }
167    }
168
169    /**
170     * Unconditionally close an <code>Reader</code>.
171     * <p>
172     * Equivalent to {@link Reader#close()}, except any exceptions will be ignored.
173     * This is typically used in finally blocks.
174     * <p>
175     * Example code:
176     * <pre>
177     *   char[] data = new char[1024];
178     *   Reader in = null;
179     *   try {
180     *       in = new FileReader("foo.txt");
181     *       in.read(data);
182     *       in.close(); //close errors are handled
183     *   } catch (Exception e) {
184     *       // error handling
185     *   } finally {
186     *       IOUtils.closeQuietly(in);
187     *   }
188     * </pre>
189     * 
190     * @param input  the Reader to close, may be null or already closed
191     */
192    public static void closeQuietly(Reader input) {
193        closeQuietly((Closeable)input);
194    }
195
196    /**
197     * Unconditionally close a <code>Writer</code>.
198     * <p>
199     * Equivalent to {@link Writer#close()}, except any exceptions will be ignored.
200     * This is typically used in finally blocks.
201     * <p>
202     * Example code:
203     * <pre>
204     *   Writer out = null;
205     *   try {
206     *       out = new StringWriter();
207     *       out.write("Hello World");
208     *       out.close(); //close errors are handled
209     *   } catch (Exception e) {
210     *       // error handling
211     *   } finally {
212     *       IOUtils.closeQuietly(out);
213     *   }
214     * </pre>
215     *
216     * @param output  the Writer to close, may be null or already closed
217     */
218    public static void closeQuietly(Writer output) {
219        closeQuietly((Closeable)output);
220    }
221
222    /**
223     * Unconditionally close an <code>InputStream</code>.
224     * <p>
225     * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored.
226     * This is typically used in finally blocks.
227     * <p>
228     * Example code:
229     * <pre>
230     *   byte[] data = new byte[1024];
231     *   InputStream in = null;
232     *   try {
233     *       in = new FileInputStream("foo.txt");
234     *       in.read(data);
235     *       in.close(); //close errors are handled
236     *   } catch (Exception e) {
237     *       // error handling
238     *   } finally {
239     *       IOUtils.closeQuietly(in);
240     *   }
241     * </pre>
242     *
243     * @param input  the InputStream to close, may be null or already closed
244     */
245    public static void closeQuietly(InputStream input) {
246        closeQuietly((Closeable)input);
247    }
248
249    /**
250     * Unconditionally close an <code>OutputStream</code>.
251     * <p>
252     * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored.
253     * This is typically used in finally blocks.
254     * <p>
255     * Example code:
256     * <pre>
257     * byte[] data = "Hello, World".getBytes();
258     *
259     * OutputStream out = null;
260     * try {
261     *     out = new FileOutputStream("foo.txt");
262     *     out.write(data);
263     *     out.close(); //close errors are handled
264     * } catch (IOException e) {
265     *     // error handling
266     * } finally {
267     *     IOUtils.closeQuietly(out);
268     * }
269     * </pre>
270     *
271     * @param output  the OutputStream to close, may be null or already closed
272     */
273    public static void closeQuietly(OutputStream output) {
274        closeQuietly((Closeable)output);
275    }
276    
277    /**
278     * Unconditionally close a <code>Closeable</code>.
279     * <p>
280     * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored.
281     * This is typically used in finally blocks.
282     * <p>
283     * Example code:
284     * <pre>
285     *   Closeable closeable = null;
286     *   try {
287     *       closeable = new FileReader("foo.txt");
288     *       // process closeable
289     *       closeable.close();
290     *   } catch (Exception e) {
291     *       // error handling
292     *   } finally {
293     *       IOUtils.closeQuietly(closeable);
294     *   }
295     * </pre>
296     *
297     * @param closeable the object to close, may be null or already closed
298     * @since 2.0
299     */
300    public static void closeQuietly(Closeable closeable) {
301        try {
302            if (closeable != null) {
303                closeable.close();
304            }
305        } catch (IOException ioe) {
306            // ignore
307        }
308    }
309
310    /**
311     * Unconditionally close a <code>Socket</code>.
312     * <p>
313     * Equivalent to {@link Socket#close()}, except any exceptions will be ignored.
314     * This is typically used in finally blocks.
315     * <p>
316     * Example code:
317     * <pre>
318     *   Socket socket = null;
319     *   try {
320     *       socket = new Socket("http://www.foo.com/", 80);
321     *       // process socket
322     *       socket.close();
323     *   } catch (Exception e) {
324     *       // error handling
325     *   } finally {
326     *       IOUtils.closeQuietly(socket);
327     *   }
328     * </pre>
329     *
330     * @param sock the Socket to close, may be null or already closed
331     * @since 2.0
332     */
333    public static void closeQuietly(Socket sock){
334        if (sock != null){
335            try {
336                sock.close();
337            } catch (IOException ioe) {
338                // ignored
339            }
340        }
341    }
342
343    /**
344     * Unconditionally close a <code>Selector</code>.
345     * <p>
346     * Equivalent to {@link Selector#close()}, except any exceptions will be ignored.
347     * This is typically used in finally blocks.
348     * <p>
349     * Example code:
350     * <pre>
351     *   Selector selector = null;
352     *   try {
353     *       selector = Selector.open();
354     *       // process socket
355     *       
356     *   } catch (Exception e) {
357     *       // error handling
358     *   } finally {
359     *       IOUtils.closeQuietly(selector);
360     *   }
361     * </pre>
362     *
363     * @param selector the Selector to close, may be null or already closed
364     * @since 2.2
365     */
366    public static void closeQuietly(Selector selector){
367        if (selector != null){
368            try {
369              selector.close();
370            } catch (IOException ioe) {
371                // ignored
372            }
373        }
374    }
375    
376    /**
377     * Unconditionally close a <code>ServerSocket</code>.
378     * <p>
379     * Equivalent to {@link ServerSocket#close()}, except any exceptions will be ignored.
380     * This is typically used in finally blocks.
381     * <p>
382     * Example code:
383     * <pre>
384     *   ServerSocket socket = null;
385     *   try {
386     *       socket = new ServerSocket();
387     *       // process socket
388     *       socket.close();
389     *   } catch (Exception e) {
390     *       // error handling
391     *   } finally {
392     *       IOUtils.closeQuietly(socket);
393     *   }
394     * </pre>
395     *
396     * @param sock the ServerSocket to close, may be null or already closed
397     * @since 2.2
398     */
399    public static void closeQuietly(ServerSocket sock){
400        if (sock != null){
401            try {
402                sock.close();
403            } catch (IOException ioe) {
404                // ignored
405            }
406        }
407    }
408
409    /**
410     * Fetches entire contents of an <code>InputStream</code> and represent
411     * same data as result InputStream.
412     * <p>
413     * This method is useful where,
414     * <ul>
415     * <li>Source InputStream is slow.</li>
416     * <li>It has network resources associated, so we cannot keep it open for
417     * long time.</li>
418     * <li>It has network timeout associated.</li>
419     * </ul>
420     * It can be used in favor of {@link #toByteArray(InputStream)}, since it
421     * avoids unnecessary allocation and copy of byte[].<br>
422     * This method buffers the input internally, so there is no need to use a
423     * <code>BufferedInputStream</code>.
424     * 
425     * @param input Stream to be fully buffered.
426     * @return A fully buffered stream.
427     * @throws IOException if an I/O error occurs
428     * @since 2.0
429     */
430    public static InputStream toBufferedInputStream(InputStream input) throws IOException {
431        return ByteArrayOutputStream.toBufferedInputStream(input);
432    }
433
434    /**
435     * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a toBufferedReader for the given
436     * reader.
437     * 
438     * @param reader
439     *            the reader to wrap or return
440     * @return the given reader or a new {@link BufferedReader} for the given reader
441     * @since 2.2
442     */
443    public static BufferedReader toBufferedReader(Reader reader) {
444        return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
445    }
446    
447    // read toByteArray
448    //-----------------------------------------------------------------------
449    /**
450     * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
451     * <p>
452     * This method buffers the input internally, so there is no need to use a
453     * <code>BufferedInputStream</code>.
454     * 
455     * @param input  the <code>InputStream</code> to read from
456     * @return the requested byte array
457     * @throws NullPointerException if the input is null
458     * @throws IOException if an I/O error occurs
459     */
460    public static byte[] toByteArray(InputStream input) throws IOException {
461        ByteArrayOutputStream output = new ByteArrayOutputStream();
462        copy(input, output);
463        return output.toByteArray();
464    }
465
466    /**
467     * Get contents of an <code>InputStream</code> as a <code>byte[]</code>.
468     * Use this method instead of <code>toByteArray(InputStream)</code>
469     * when <code>InputStream</code> size is known.
470     * <b>NOTE:</b> the method checks that the length can safely be cast to an int without truncation
471     * before using {@link IOUtils#toByteArray(java.io.InputStream, int)} to read into the byte array.
472     * (Arrays can have no more than Integer.MAX_VALUE entries anyway)
473     * 
474     * @param input the <code>InputStream</code> to read from
475     * @param size the size of <code>InputStream</code>
476     * @return the requested byte array
477     * @throws IOException if an I/O error occurs or <code>InputStream</code> size differ from parameter size
478     * @throws IllegalArgumentException if size is less than zero or size is greater than Integer.MAX_VALUE
479     * @see IOUtils#toByteArray(java.io.InputStream, int)
480     * @since 2.1
481     */
482    public static byte[] toByteArray(InputStream input, long size) throws IOException {
483
484      if(size > Integer.MAX_VALUE) {
485          throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size);
486      }
487
488      return toByteArray(input, (int) size);
489    }
490
491    /** 
492     * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
493     * Use this method instead of <code>toByteArray(InputStream)</code>
494     * when <code>InputStream</code> size is known
495     * @param input the <code>InputStream</code> to read from
496     * @param size the size of <code>InputStream</code>
497     * @return the requested byte array
498     * @throws IOException if an I/O error occurs or <code>InputStream</code> size differ from parameter size
499     * @throws IllegalArgumentException if size is less than zero
500     * @since 2.1
501     */
502    public static byte[] toByteArray(InputStream input, int size) throws IOException {
503
504        if (size < 0) {
505            throw new IllegalArgumentException("Size must be equal or greater than zero: " + size);
506        }
507
508        if (size == 0) {
509            return new byte[0];
510        }
511
512        byte[] data = new byte[size];
513        int offset = 0;
514        int readed;
515
516        while (offset < size && (readed = input.read(data, offset, size - offset)) != EOF) {
517            offset += readed;
518        }
519
520        if (offset != size) {
521            throw new IOException("Unexpected readed size. current: " + offset + ", excepted: " + size);
522        }
523
524        return data;
525    }
526
527    /**
528     * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
529     * using the default character encoding of the platform.
530     * <p>
531     * This method buffers the input internally, so there is no need to use a
532     * <code>BufferedReader</code>.
533     * 
534     * @param input  the <code>Reader</code> to read from
535     * @return the requested byte array
536     * @throws NullPointerException if the input is null
537     * @throws IOException if an I/O error occurs
538     */
539    public static byte[] toByteArray(Reader input) throws IOException {
540        return toByteArray(input, Charset.defaultCharset());
541    }
542
543    /**
544     * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
545     * using the specified character encoding.
546     * <p>
547     * This method buffers the input internally, so there is no need to use a
548     * <code>BufferedReader</code>.
549     * 
550     * @param input  the <code>Reader</code> to read from
551     * @param encoding  the encoding to use, null means platform default
552     * @return the requested byte array
553     * @throws NullPointerException if the input is null
554     * @throws IOException if an I/O error occurs
555     * @since 2.3
556     */
557    public static byte[] toByteArray(Reader input, Charset encoding) throws IOException {
558        ByteArrayOutputStream output = new ByteArrayOutputStream();
559        copy(input, output, encoding);
560        return output.toByteArray();
561    }
562
563    /**
564     * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
565     * using the specified character encoding.
566     * <p>
567     * Character encoding names can be found at
568     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
569     * <p>
570     * This method buffers the input internally, so there is no need to use a
571     * <code>BufferedReader</code>.
572     * 
573     * @param input  the <code>Reader</code> to read from
574     * @param encoding  the encoding to use, null means platform default
575     * @return the requested byte array
576     * @throws NullPointerException if the input is null
577     * @throws IOException if an I/O error occurs
578     * @throws UnsupportedCharsetException
579     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
580     *             supported.
581     * @since 1.1
582     */
583    public static byte[] toByteArray(Reader input, String encoding) throws IOException {
584        return toByteArray(input, Charsets.toCharset(encoding));
585    }
586
587    /**
588     * Get the contents of a <code>String</code> as a <code>byte[]</code>
589     * using the default character encoding of the platform.
590     * <p>
591     * This is the same as {@link String#getBytes()}.
592     * 
593     * @param input  the <code>String</code> to convert
594     * @return the requested byte array
595     * @throws NullPointerException if the input is null
596     * @throws IOException if an I/O error occurs (never occurs)
597     * @deprecated Use {@link String#getBytes()}
598     */
599    @Deprecated
600    public static byte[] toByteArray(String input) throws IOException {
601        return input.getBytes();
602    }
603
604    /**
605     * Get the contents of a <code>URI</code> as a <code>byte[]</code>.
606     * 
607     * @param uri
608     *            the <code>URI</code> to read
609     * @return the requested byte array
610     * @throws NullPointerException
611     *             if the uri is null
612     * @throws IOException
613     *             if an I/O exception occurs
614     * @since 2.4
615     */
616    public static byte[] toByteArray(URI uri) throws IOException {
617        return IOUtils.toByteArray(uri.toURL());
618    }
619
620    /**
621     * Get the contents of a <code>URL</code> as a <code>byte[]</code>.
622     * 
623     * @param url
624     *            the <code>URL</code> to read
625     * @return the requested byte array
626     * @throws NullPointerException
627     *             if the input is null
628     * @throws IOException
629     *             if an I/O exception occurs
630     * @since 2.4
631     */
632    public static byte[] toByteArray(URL url) throws IOException {
633        URLConnection conn = url.openConnection();
634        try {
635            return IOUtils.toByteArray(conn);
636        } finally {
637            close(conn);
638        }
639    }
640
641    /**
642     * Get the contents of a <code>URLConnection</code> as a <code>byte[]</code>.
643     * 
644     * @param urlConn
645     *            the <code>URLConnection</code> to read
646     * @return the requested byte array
647     * @throws NullPointerException
648     *             if the urlConn is null
649     * @throws IOException
650     *             if an I/O exception occurs
651     * @since 2.4
652     */
653    public static byte[] toByteArray(URLConnection urlConn) throws IOException {
654        InputStream inputStream = urlConn.getInputStream();
655        try {
656            return IOUtils.toByteArray(inputStream);
657        } finally {
658            inputStream.close();
659        }
660    }
661
662    // read char[]
663    //-----------------------------------------------------------------------
664    /**
665     * Get the contents of an <code>InputStream</code> as a character array
666     * using the default character encoding of the platform.
667     * <p>
668     * This method buffers the input internally, so there is no need to use a
669     * <code>BufferedInputStream</code>.
670     * 
671     * @param is  the <code>InputStream</code> to read from
672     * @return the requested character array
673     * @throws NullPointerException if the input is null
674     * @throws IOException if an I/O error occurs
675     * @since 1.1
676     */
677    public static char[] toCharArray(InputStream is) throws IOException {
678        return toCharArray(is, Charset.defaultCharset());
679    }
680
681    /**
682     * Get the contents of an <code>InputStream</code> as a character array
683     * using the specified character encoding.
684     * <p>
685     * This method buffers the input internally, so there is no need to use a
686     * <code>BufferedInputStream</code>.
687     * 
688     * @param is  the <code>InputStream</code> to read from
689     * @param encoding  the encoding to use, null means platform default
690     * @return the requested character array
691     * @throws NullPointerException if the input is null
692     * @throws IOException if an I/O error occurs
693     * @since 2.3
694     */
695    public static char[] toCharArray(InputStream is, Charset encoding)
696            throws IOException {
697        CharArrayWriter output = new CharArrayWriter();
698        copy(is, output, encoding);
699        return output.toCharArray();
700    }
701
702    /**
703     * Get the contents of an <code>InputStream</code> as a character array
704     * using the specified character encoding.
705     * <p>
706     * Character encoding names can be found at
707     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
708     * <p>
709     * This method buffers the input internally, so there is no need to use a
710     * <code>BufferedInputStream</code>.
711     * 
712     * @param is  the <code>InputStream</code> to read from
713     * @param encoding  the encoding to use, null means platform default
714     * @return the requested character array
715     * @throws NullPointerException if the input is null
716     * @throws IOException if an I/O error occurs
717     * @throws UnsupportedCharsetException
718     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
719     *             supported.
720     * @since 1.1
721     */
722    public static char[] toCharArray(InputStream is, String encoding) throws IOException {
723        return toCharArray(is, Charsets.toCharset(encoding));
724    }
725
726    /**
727     * Get the contents of a <code>Reader</code> as a character array.
728     * <p>
729     * This method buffers the input internally, so there is no need to use a
730     * <code>BufferedReader</code>.
731     * 
732     * @param input  the <code>Reader</code> to read from
733     * @return the requested character array
734     * @throws NullPointerException if the input is null
735     * @throws IOException if an I/O error occurs
736     * @since 1.1
737     */
738    public static char[] toCharArray(Reader input) throws IOException {
739        CharArrayWriter sw = new CharArrayWriter();
740        copy(input, sw);
741        return sw.toCharArray();
742    }
743
744    // read toString
745    //-----------------------------------------------------------------------
746    /**
747     * Get the contents of an <code>InputStream</code> as a String
748     * using the default character encoding of the platform.
749     * <p>
750     * This method buffers the input internally, so there is no need to use a
751     * <code>BufferedInputStream</code>.
752     * 
753     * @param input  the <code>InputStream</code> to read from
754     * @return the requested String
755     * @throws NullPointerException if the input is null
756     * @throws IOException if an I/O error occurs
757     */
758    public static String toString(InputStream input) throws IOException {
759        return toString(input, Charset.defaultCharset());
760    }
761
762    /**
763     * Get the contents of an <code>InputStream</code> as a String
764     * using the specified character encoding.
765     * <p>
766     * This method buffers the input internally, so there is no need to use a
767     * <code>BufferedInputStream</code>.
768     * </p>
769     * @param input  the <code>InputStream</code> to read from
770     * @param encoding  the encoding to use, null means platform default
771     * @return the requested String
772     * @throws NullPointerException if the input is null
773     * @throws IOException if an I/O error occurs
774     * @since 2.3
775     */
776    public static String toString(InputStream input, Charset encoding) throws IOException {
777        StringBuilderWriter sw = new StringBuilderWriter();
778        copy(input, sw, encoding);
779        return sw.toString();
780    }
781
782    /**
783     * Get the contents of an <code>InputStream</code> as a String
784     * using the specified character encoding.
785     * <p>
786     * Character encoding names can be found at
787     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
788     * <p>
789     * This method buffers the input internally, so there is no need to use a
790     * <code>BufferedInputStream</code>.
791     * 
792     * @param input  the <code>InputStream</code> to read from
793     * @param encoding  the encoding to use, null means platform default
794     * @return the requested String
795     * @throws NullPointerException if the input is null
796     * @throws IOException if an I/O error occurs
797     * @throws UnsupportedCharsetException
798     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
799     *             supported.
800     */
801    public static String toString(InputStream input, String encoding)
802            throws IOException {
803        return toString(input, Charsets.toCharset(encoding));
804    }
805
806    /**
807     * Get the contents of a <code>Reader</code> as a String.
808     * <p>
809     * This method buffers the input internally, so there is no need to use a
810     * <code>BufferedReader</code>.
811     * 
812     * @param input  the <code>Reader</code> to read from
813     * @return the requested String
814     * @throws NullPointerException if the input is null
815     * @throws IOException if an I/O error occurs
816     */
817    public static String toString(Reader input) throws IOException {
818        StringBuilderWriter sw = new StringBuilderWriter();
819        copy(input, sw);
820        return sw.toString();
821    }
822
823    /**
824     * Gets the contents at the given URI.
825     * 
826     * @param uri
827     *            The URI source.
828     * @return The contents of the URL as a String.
829     * @throws IOException if an I/O exception occurs.
830     * @since 2.1
831     */
832    public static String toString(URI uri) throws IOException {
833        return toString(uri, Charset.defaultCharset());
834    }
835
836    /**
837     * Gets the contents at the given URI.
838     * 
839     * @param uri
840     *            The URI source.
841     * @param encoding
842     *            The encoding name for the URL contents.
843     * @return The contents of the URL as a String.
844     * @throws IOException if an I/O exception occurs.
845     * @since 2.3.
846     */
847    public static String toString(URI uri, Charset encoding) throws IOException {
848        return toString(uri.toURL(), Charsets.toCharset(encoding));
849    }
850
851    /**
852     * Gets the contents at the given URI.
853     * 
854     * @param uri
855     *            The URI source.
856     * @param encoding
857     *            The encoding name for the URL contents.
858     * @return The contents of the URL as a String.
859     * @throws IOException if an I/O exception occurs.
860     * @throws UnsupportedCharsetException
861     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
862     *             supported.
863     * @since 2.1
864     */
865    public static String toString(URI uri, String encoding) throws IOException {
866        return toString(uri, Charsets.toCharset(encoding));
867    }
868
869    /**
870     * Gets the contents at the given URL.
871     * 
872     * @param url
873     *            The URL source.
874     * @return The contents of the URL as a String.
875     * @throws IOException if an I/O exception occurs.
876     * @since 2.1
877     */
878    public static String toString(URL url) throws IOException {
879        return toString(url, Charset.defaultCharset());
880    }
881
882    /**
883     * Gets the contents at the given URL.
884     * 
885     * @param url
886     *            The URL source.
887     * @param encoding
888     *            The encoding name for the URL contents.
889     * @return The contents of the URL as a String.
890     * @throws IOException if an I/O exception occurs.
891     * @since 2.3
892     */
893    public static String toString(URL url, Charset encoding) throws IOException {
894        InputStream inputStream = url.openStream();
895        try {
896            return toString(inputStream, encoding);
897        } finally {
898            inputStream.close();
899        }
900    }
901
902    /**
903     * Gets the contents at the given URL.
904     * 
905     * @param url
906     *            The URL source.
907     * @param encoding
908     *            The encoding name for the URL contents.
909     * @return The contents of the URL as a String.
910     * @throws IOException if an I/O exception occurs.
911     * @throws UnsupportedCharsetException
912     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
913     *             supported.
914     * @since 2.1
915     */
916    public static String toString(URL url, String encoding) throws IOException {
917        return toString(url, Charsets.toCharset(encoding));
918    }
919
920    /**
921     * Get the contents of a <code>byte[]</code> as a String
922     * using the default character encoding of the platform.
923     * 
924     * @param input the byte array to read from
925     * @return the requested String
926     * @throws NullPointerException if the input is null
927     * @throws IOException if an I/O error occurs (never occurs)
928     * @deprecated Use {@link String#String(byte[])}
929     */
930    @Deprecated
931    public static String toString(byte[] input) throws IOException {
932        return new String(input);
933    }
934
935    /**
936     * Get the contents of a <code>byte[]</code> as a String
937     * using the specified character encoding.
938     * <p>
939     * Character encoding names can be found at
940     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
941     * 
942     * @param input the byte array to read from
943     * @param encoding  the encoding to use, null means platform default
944     * @return the requested String
945     * @throws NullPointerException if the input is null
946     * @throws IOException if an I/O error occurs (never occurs)
947     */
948    public static String toString(byte[] input, String encoding) throws IOException {
949        return new String(input, Charsets.toCharset(encoding));
950    }
951
952    // readLines
953    //-----------------------------------------------------------------------
954    /**
955     * Get the contents of an <code>InputStream</code> as a list of Strings,
956     * one entry per line, using the default character encoding of the platform.
957     * <p>
958     * This method buffers the input internally, so there is no need to use a
959     * <code>BufferedInputStream</code>.
960     *
961     * @param input  the <code>InputStream</code> to read from, not null
962     * @return the list of Strings, never null
963     * @throws NullPointerException if the input is null
964     * @throws IOException if an I/O error occurs
965     * @since 1.1
966     */
967    public static List<String> readLines(InputStream input) throws IOException {
968        return readLines(input, Charset.defaultCharset());
969    }
970
971    /**
972     * Get the contents of an <code>InputStream</code> as a list of Strings,
973     * one entry per line, using the specified character encoding.
974     * <p>
975     * This method buffers the input internally, so there is no need to use a
976     * <code>BufferedInputStream</code>.
977     *
978     * @param input  the <code>InputStream</code> to read from, not null
979     * @param encoding  the encoding to use, null means platform default
980     * @return the list of Strings, never null
981     * @throws NullPointerException if the input is null
982     * @throws IOException if an I/O error occurs
983     * @since 2.3
984     */
985    public static List<String> readLines(InputStream input, Charset encoding) throws IOException {
986        InputStreamReader reader = new InputStreamReader(input, Charsets.toCharset(encoding));
987        return readLines(reader);
988    }
989
990    /**
991     * Get the contents of an <code>InputStream</code> as a list of Strings,
992     * one entry per line, using the specified character encoding.
993     * <p>
994     * Character encoding names can be found at
995     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
996     * <p>
997     * This method buffers the input internally, so there is no need to use a
998     * <code>BufferedInputStream</code>.
999     *
1000     * @param input  the <code>InputStream</code> to read from, not null
1001     * @param encoding  the encoding to use, null means platform default
1002     * @return the list of Strings, never null
1003     * @throws NullPointerException if the input is null
1004     * @throws IOException if an I/O error occurs
1005     * @throws UnsupportedCharsetException
1006     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1007     *             supported.
1008     * @since 1.1
1009     */
1010    public static List<String> readLines(InputStream input, String encoding) throws IOException {
1011        return readLines(input, Charsets.toCharset(encoding));
1012    }
1013
1014    /**
1015     * Get the contents of a <code>Reader</code> as a list of Strings,
1016     * one entry per line.
1017     * <p>
1018     * This method buffers the input internally, so there is no need to use a
1019     * <code>BufferedReader</code>.
1020     *
1021     * @param input  the <code>Reader</code> to read from, not null
1022     * @return the list of Strings, never null
1023     * @throws NullPointerException if the input is null
1024     * @throws IOException if an I/O error occurs
1025     * @since 1.1
1026     */
1027    public static List<String> readLines(Reader input) throws IOException {
1028        BufferedReader reader = toBufferedReader(input);
1029        List<String> list = new ArrayList<String>();
1030        String line = reader.readLine();
1031        while (line != null) {
1032            list.add(line);
1033            line = reader.readLine();
1034        }
1035        return list;
1036    }
1037
1038    // lineIterator
1039    //-----------------------------------------------------------------------
1040    /**
1041     * Return an Iterator for the lines in a <code>Reader</code>.
1042     * <p>
1043     * <code>LineIterator</code> holds a reference to the open
1044     * <code>Reader</code> specified here. When you have finished with the
1045     * iterator you should close the reader to free internal resources.
1046     * This can be done by closing the reader directly, or by calling
1047     * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
1048     * <p>
1049     * The recommended usage pattern is:
1050     * <pre>
1051     * try {
1052     *   LineIterator it = IOUtils.lineIterator(reader);
1053     *   while (it.hasNext()) {
1054     *     String line = it.nextLine();
1055     *     /// do something with line
1056     *   }
1057     * } finally {
1058     *   IOUtils.closeQuietly(reader);
1059     * }
1060     * </pre>
1061     *
1062     * @param reader  the <code>Reader</code> to read from, not null
1063     * @return an Iterator of the lines in the reader, never null
1064     * @throws IllegalArgumentException if the reader is null
1065     * @since 1.2
1066     */
1067    public static LineIterator lineIterator(Reader reader) {
1068        return new LineIterator(reader);
1069    }
1070
1071    /**
1072     * Return an Iterator for the lines in an <code>InputStream</code>, using
1073     * the character encoding specified (or default encoding if null).
1074     * <p>
1075     * <code>LineIterator</code> holds a reference to the open
1076     * <code>InputStream</code> specified here. When you have finished with
1077     * the iterator you should close the stream to free internal resources.
1078     * This can be done by closing the stream directly, or by calling
1079     * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
1080     * <p>
1081     * The recommended usage pattern is:
1082     * <pre>
1083     * try {
1084     *   LineIterator it = IOUtils.lineIterator(stream, charset);
1085     *   while (it.hasNext()) {
1086     *     String line = it.nextLine();
1087     *     /// do something with line
1088     *   }
1089     * } finally {
1090     *   IOUtils.closeQuietly(stream);
1091     * }
1092     * </pre>
1093     *
1094     * @param input  the <code>InputStream</code> to read from, not null
1095     * @param encoding  the encoding to use, null means platform default
1096     * @return an Iterator of the lines in the reader, never null
1097     * @throws IllegalArgumentException if the input is null
1098     * @throws IOException if an I/O error occurs, such as if the encoding is invalid
1099     * @since 2.3
1100     */
1101    public static LineIterator lineIterator(InputStream input, Charset encoding) throws IOException {
1102        return new LineIterator(new InputStreamReader(input, Charsets.toCharset(encoding)));
1103    }
1104
1105    /**
1106     * Return an Iterator for the lines in an <code>InputStream</code>, using
1107     * the character encoding specified (or default encoding if null).
1108     * <p>
1109     * <code>LineIterator</code> holds a reference to the open
1110     * <code>InputStream</code> specified here. When you have finished with
1111     * the iterator you should close the stream to free internal resources.
1112     * This can be done by closing the stream directly, or by calling
1113     * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
1114     * <p>
1115     * The recommended usage pattern is:
1116     * <pre>
1117     * try {
1118     *   LineIterator it = IOUtils.lineIterator(stream, "UTF-8");
1119     *   while (it.hasNext()) {
1120     *     String line = it.nextLine();
1121     *     /// do something with line
1122     *   }
1123     * } finally {
1124     *   IOUtils.closeQuietly(stream);
1125     * }
1126     * </pre>
1127     *
1128     * @param input  the <code>InputStream</code> to read from, not null
1129     * @param encoding  the encoding to use, null means platform default
1130     * @return an Iterator of the lines in the reader, never null
1131     * @throws IllegalArgumentException if the input is null
1132     * @throws IOException if an I/O error occurs, such as if the encoding is invalid
1133     * @throws UnsupportedCharsetException
1134     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1135     *             supported.
1136     * @since 1.2
1137     */
1138    public static LineIterator lineIterator(InputStream input, String encoding) throws IOException {
1139        return lineIterator(input, Charsets.toCharset(encoding));
1140    }
1141
1142    //-----------------------------------------------------------------------
1143    /**
1144     * Convert the specified CharSequence to an input stream, encoded as bytes
1145     * using the default character encoding of the platform.
1146     *
1147     * @param input the CharSequence to convert
1148     * @return an input stream
1149     * @since 2.0
1150     */
1151    public static InputStream toInputStream(CharSequence input) {
1152        return toInputStream(input, Charset.defaultCharset());
1153    }
1154
1155    /**
1156     * Convert the specified CharSequence to an input stream, encoded as bytes
1157     * using the specified character encoding.
1158     *
1159     * @param input the CharSequence to convert
1160     * @param encoding the encoding to use, null means platform default
1161     * @return an input stream
1162     * @since 2.3
1163     */
1164    public static InputStream toInputStream(CharSequence input, Charset encoding) {
1165        return toInputStream(input.toString(), encoding);
1166    }
1167
1168    /**
1169     * Convert the specified CharSequence to an input stream, encoded as bytes
1170     * using the specified character encoding.
1171     * <p>
1172     * Character encoding names can be found at
1173     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1174     *
1175     * @param input the CharSequence to convert
1176     * @param encoding the encoding to use, null means platform default
1177     * @return an input stream
1178     * @throws IOException if the encoding is invalid
1179     * @throws UnsupportedCharsetException
1180     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1181     *             supported.
1182     * @since 2.0
1183     */
1184    public static InputStream toInputStream(CharSequence input, String encoding) throws IOException {
1185        return toInputStream(input, Charsets.toCharset(encoding));
1186    }
1187
1188    //-----------------------------------------------------------------------
1189    /**
1190     * Convert the specified string to an input stream, encoded as bytes
1191     * using the default character encoding of the platform.
1192     *
1193     * @param input the string to convert
1194     * @return an input stream
1195     * @since 1.1
1196     */
1197    public static InputStream toInputStream(String input) {
1198        return toInputStream(input, Charset.defaultCharset());
1199    }
1200
1201    /**
1202     * Convert the specified string to an input stream, encoded as bytes
1203     * using the specified character encoding.
1204     *
1205     * @param input the string to convert
1206     * @param encoding the encoding to use, null means platform default
1207     * @return an input stream
1208     * @since 2.3
1209     */
1210    public static InputStream toInputStream(String input, Charset encoding) {
1211        return new ByteArrayInputStream(input.getBytes(Charsets.toCharset(encoding)));
1212    }
1213
1214    /**
1215     * Convert the specified string to an input stream, encoded as bytes
1216     * using the specified character encoding.
1217     * <p>
1218     * Character encoding names can be found at
1219     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1220     *
1221     * @param input the string to convert
1222     * @param encoding the encoding to use, null means platform default
1223     * @return an input stream
1224     * @throws IOException if the encoding is invalid
1225     * @throws UnsupportedCharsetException
1226     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1227     *             supported.
1228     * @since 1.1
1229     */
1230    public static InputStream toInputStream(String input, String encoding) throws IOException {
1231        byte[] bytes = input.getBytes(Charsets.toCharset(encoding));
1232        return new ByteArrayInputStream(bytes);
1233    }
1234
1235    // write byte[]
1236    //-----------------------------------------------------------------------
1237    /**
1238     * Writes bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
1239     * 
1240     * @param data  the byte array to write, do not modify during output,
1241     * null ignored
1242     * @param output  the <code>OutputStream</code> to write to
1243     * @throws NullPointerException if output is null
1244     * @throws IOException if an I/O error occurs
1245     * @since 1.1
1246     */
1247    public static void write(byte[] data, OutputStream output)
1248            throws IOException {
1249        if (data != null) {
1250            output.write(data);
1251        }
1252    }
1253
1254    /**
1255     * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
1256     * using the default character encoding of the platform.
1257     * <p>
1258     * This method uses {@link String#String(byte[])}.
1259     * 
1260     * @param data  the byte array to write, do not modify during output,
1261     * null ignored
1262     * @param output  the <code>Writer</code> to write to
1263     * @throws NullPointerException if output is null
1264     * @throws IOException if an I/O error occurs
1265     * @since 1.1
1266     */
1267    public static void write(byte[] data, Writer output) throws IOException {
1268        write(data, output, Charset.defaultCharset());
1269    }
1270
1271    /**
1272     * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
1273     * using the specified character encoding.
1274     * <p>
1275     * This method uses {@link String#String(byte[], String)}.
1276     * 
1277     * @param data  the byte array to write, do not modify during output,
1278     * null ignored
1279     * @param output  the <code>Writer</code> to write to
1280     * @param encoding  the encoding to use, null means platform default
1281     * @throws NullPointerException if output is null
1282     * @throws IOException if an I/O error occurs
1283     * @since 2.3
1284     */
1285    public static void write(byte[] data, Writer output, Charset encoding) throws IOException {
1286        if (data != null) {
1287            output.write(new String(data, Charsets.toCharset(encoding)));
1288        }
1289    }
1290
1291    /**
1292     * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
1293     * using the specified character encoding.
1294     * <p>
1295     * Character encoding names can be found at
1296     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1297     * <p>
1298     * This method uses {@link String#String(byte[], String)}.
1299     * 
1300     * @param data  the byte array to write, do not modify during output,
1301     * null ignored
1302     * @param output  the <code>Writer</code> to write to
1303     * @param encoding  the encoding to use, null means platform default
1304     * @throws NullPointerException if output is null
1305     * @throws IOException if an I/O error occurs
1306     * @throws UnsupportedCharsetException
1307     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1308     *             supported.
1309     * @since 1.1
1310     */
1311    public static void write(byte[] data, Writer output, String encoding) throws IOException {
1312        write(data, output, Charsets.toCharset(encoding));
1313    }
1314
1315    // write char[]
1316    //-----------------------------------------------------------------------
1317    /**
1318     * Writes chars from a <code>char[]</code> to a <code>Writer</code>
1319     * using the default character encoding of the platform.
1320     * 
1321     * @param data  the char array to write, do not modify during output,
1322     * null ignored
1323     * @param output  the <code>Writer</code> to write to
1324     * @throws NullPointerException if output is null
1325     * @throws IOException if an I/O error occurs
1326     * @since 1.1
1327     */
1328    public static void write(char[] data, Writer output) throws IOException {
1329        if (data != null) {
1330            output.write(data);
1331        }
1332    }
1333
1334    /**
1335     * Writes chars from a <code>char[]</code> to bytes on an
1336     * <code>OutputStream</code>.
1337     * <p>
1338     * This method uses {@link String#String(char[])} and
1339     * {@link String#getBytes()}.
1340     * 
1341     * @param data  the char array to write, do not modify during output,
1342     * null ignored
1343     * @param output  the <code>OutputStream</code> to write to
1344     * @throws NullPointerException if output is null
1345     * @throws IOException if an I/O error occurs
1346     * @since 1.1
1347     */
1348    public static void write(char[] data, OutputStream output)
1349            throws IOException {
1350        write(data, output, Charset.defaultCharset());
1351    }
1352
1353    /**
1354     * Writes chars from a <code>char[]</code> to bytes on an
1355     * <code>OutputStream</code> using the specified character encoding.
1356     * <p>
1357     * This method uses {@link String#String(char[])} and
1358     * {@link String#getBytes(String)}.
1359     * 
1360     * @param data  the char array to write, do not modify during output,
1361     * null ignored
1362     * @param output  the <code>OutputStream</code> to write to
1363     * @param encoding  the encoding to use, null means platform default
1364     * @throws NullPointerException if output is null
1365     * @throws IOException if an I/O error occurs
1366     * @since 2.3
1367     */
1368    public static void write(char[] data, OutputStream output, Charset encoding) throws IOException {
1369        if (data != null) {
1370            output.write(new String(data).getBytes(Charsets.toCharset(encoding)));
1371        }
1372    }
1373
1374    /**
1375     * Writes chars from a <code>char[]</code> to bytes on an
1376     * <code>OutputStream</code> using the specified character encoding.
1377     * <p>
1378     * Character encoding names can be found at
1379     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1380     * <p>
1381     * This method uses {@link String#String(char[])} and
1382     * {@link String#getBytes(String)}.
1383     * 
1384     * @param data  the char array to write, do not modify during output,
1385     * null ignored
1386     * @param output  the <code>OutputStream</code> to write to
1387     * @param encoding  the encoding to use, null means platform default
1388     * @throws NullPointerException if output is null
1389     * @throws IOException if an I/O error occurs
1390     * @throws UnsupportedCharsetException
1391     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1392     *             supported.
1393     * @since 1.1
1394     */
1395    public static void write(char[] data, OutputStream output, String encoding)
1396            throws IOException {
1397        write(data, output, Charsets.toCharset(encoding));
1398    }
1399
1400    // write CharSequence
1401    //-----------------------------------------------------------------------
1402    /**
1403     * Writes chars from a <code>CharSequence</code> to a <code>Writer</code>.
1404     * 
1405     * @param data  the <code>CharSequence</code> to write, null ignored
1406     * @param output  the <code>Writer</code> to write to
1407     * @throws NullPointerException if output is null
1408     * @throws IOException if an I/O error occurs
1409     * @since 2.0
1410     */
1411    public static void write(CharSequence data, Writer output) throws IOException {
1412        if (data != null) {
1413            write(data.toString(), output);
1414        }
1415    }
1416
1417    /**
1418     * Writes chars from a <code>CharSequence</code> to bytes on an
1419     * <code>OutputStream</code> using the default character encoding of the
1420     * platform.
1421     * <p>
1422     * This method uses {@link String#getBytes()}.
1423     * 
1424     * @param data  the <code>CharSequence</code> to write, null ignored
1425     * @param output  the <code>OutputStream</code> to write to
1426     * @throws NullPointerException if output is null
1427     * @throws IOException if an I/O error occurs
1428     * @since 2.0
1429     */
1430    public static void write(CharSequence data, OutputStream output)
1431            throws IOException {
1432        write(data, output, Charset.defaultCharset());
1433    }
1434
1435    /**
1436     * Writes chars from a <code>CharSequence</code> to bytes on an
1437     * <code>OutputStream</code> using the specified character encoding.
1438     * <p>
1439     * This method uses {@link String#getBytes(String)}.
1440     * 
1441     * @param data  the <code>CharSequence</code> to write, null ignored
1442     * @param output  the <code>OutputStream</code> to write to
1443     * @param encoding  the encoding to use, null means platform default
1444     * @throws NullPointerException if output is null
1445     * @throws IOException if an I/O error occurs
1446     * @since 2.3
1447     */
1448    public static void write(CharSequence data, OutputStream output, Charset encoding) throws IOException {
1449        if (data != null) {
1450            write(data.toString(), output, encoding);
1451        }
1452    }
1453
1454    /**
1455     * Writes chars from a <code>CharSequence</code> to bytes on an
1456     * <code>OutputStream</code> using the specified character encoding.
1457     * <p>
1458     * Character encoding names can be found at
1459     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1460     * <p>
1461     * This method uses {@link String#getBytes(String)}.
1462     * 
1463     * @param data  the <code>CharSequence</code> to write, null ignored
1464     * @param output  the <code>OutputStream</code> to write to
1465     * @param encoding  the encoding to use, null means platform default
1466     * @throws NullPointerException if output is null
1467     * @throws IOException if an I/O error occurs
1468     * @throws UnsupportedCharsetException
1469     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1470     *             supported.
1471     * @since 2.0
1472     */
1473    public static void write(CharSequence data, OutputStream output, String encoding) throws IOException {
1474        write(data, output, Charsets.toCharset(encoding));
1475    }
1476
1477    // write String
1478    //-----------------------------------------------------------------------
1479    /**
1480     * Writes chars from a <code>String</code> to a <code>Writer</code>.
1481     * 
1482     * @param data  the <code>String</code> to write, null ignored
1483     * @param output  the <code>Writer</code> to write to
1484     * @throws NullPointerException if output is null
1485     * @throws IOException if an I/O error occurs
1486     * @since 1.1
1487     */
1488    public static void write(String data, Writer output) throws IOException {
1489        if (data != null) {
1490            output.write(data);
1491        }
1492    }
1493
1494    /**
1495     * Writes chars from a <code>String</code> to bytes on an
1496     * <code>OutputStream</code> using the default character encoding of the
1497     * platform.
1498     * <p>
1499     * This method uses {@link String#getBytes()}.
1500     * 
1501     * @param data  the <code>String</code> to write, null ignored
1502     * @param output  the <code>OutputStream</code> to write to
1503     * @throws NullPointerException if output is null
1504     * @throws IOException if an I/O error occurs
1505     * @since 1.1
1506     */
1507    public static void write(String data, OutputStream output)
1508            throws IOException {
1509        write(data, output, Charset.defaultCharset());
1510    }
1511
1512    /**
1513     * Writes chars from a <code>String</code> to bytes on an
1514     * <code>OutputStream</code> using the specified character encoding.
1515     * <p>
1516     * This method uses {@link String#getBytes(String)}.
1517     * 
1518     * @param data  the <code>String</code> to write, null ignored
1519     * @param output  the <code>OutputStream</code> to write to
1520     * @param encoding  the encoding to use, null means platform default
1521     * @throws NullPointerException if output is null
1522     * @throws IOException if an I/O error occurs
1523     * @since 2.3
1524     */
1525    public static void write(String data, OutputStream output, Charset encoding) throws IOException {
1526        if (data != null) {
1527            output.write(data.getBytes(Charsets.toCharset(encoding)));
1528        }
1529    }
1530
1531    /**
1532     * Writes chars from a <code>String</code> to bytes on an
1533     * <code>OutputStream</code> using the specified character encoding.
1534     * <p>
1535     * Character encoding names can be found at
1536     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1537     * <p>
1538     * This method uses {@link String#getBytes(String)}.
1539     * 
1540     * @param data  the <code>String</code> to write, null ignored
1541     * @param output  the <code>OutputStream</code> to write to
1542     * @param encoding  the encoding to use, null means platform default
1543     * @throws NullPointerException if output is null
1544     * @throws IOException if an I/O error occurs
1545     * @throws UnsupportedCharsetException
1546     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1547     *             supported.
1548     * @since 1.1
1549     */
1550    public static void write(String data, OutputStream output, String encoding)
1551            throws IOException {
1552        write(data, output, Charsets.toCharset(encoding));
1553    }
1554
1555    // write StringBuffer
1556    //-----------------------------------------------------------------------
1557    /**
1558     * Writes chars from a <code>StringBuffer</code> to a <code>Writer</code>.
1559     * 
1560     * @param data  the <code>StringBuffer</code> to write, null ignored
1561     * @param output  the <code>Writer</code> to write to
1562     * @throws NullPointerException if output is null
1563     * @throws IOException if an I/O error occurs
1564     * @since 1.1
1565     * @deprecated replaced by write(CharSequence, Writer)
1566     */
1567    @Deprecated
1568    public static void write(StringBuffer data, Writer output)
1569            throws IOException {
1570        if (data != null) {
1571            output.write(data.toString());
1572        }
1573    }
1574
1575    /**
1576     * Writes chars from a <code>StringBuffer</code> to bytes on an
1577     * <code>OutputStream</code> using the default character encoding of the
1578     * platform.
1579     * <p>
1580     * This method uses {@link String#getBytes()}.
1581     * 
1582     * @param data  the <code>StringBuffer</code> to write, null ignored
1583     * @param output  the <code>OutputStream</code> to write to
1584     * @throws NullPointerException if output is null
1585     * @throws IOException if an I/O error occurs
1586     * @since 1.1
1587     * @deprecated replaced by write(CharSequence, OutputStream)
1588     */
1589    @Deprecated
1590    public static void write(StringBuffer data, OutputStream output)
1591            throws IOException {
1592        write(data, output, (String) null);
1593    }
1594
1595    /**
1596     * Writes chars from a <code>StringBuffer</code> to bytes on an
1597     * <code>OutputStream</code> using the specified character encoding.
1598     * <p>
1599     * Character encoding names can be found at
1600     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1601     * <p>
1602     * This method uses {@link String#getBytes(String)}.
1603     * 
1604     * @param data  the <code>StringBuffer</code> to write, null ignored
1605     * @param output  the <code>OutputStream</code> to write to
1606     * @param encoding  the encoding to use, null means platform default
1607     * @throws NullPointerException if output is null
1608     * @throws IOException if an I/O error occurs
1609     * @throws UnsupportedCharsetException
1610     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1611     *             supported.
1612     * @since 1.1
1613     * @deprecated replaced by write(CharSequence, OutputStream, String)
1614     */
1615    @Deprecated
1616    public static void write(StringBuffer data, OutputStream output, String encoding) throws IOException {
1617        if (data != null) {
1618            output.write(data.toString().getBytes(Charsets.toCharset(encoding)));
1619        }
1620    }
1621
1622    // writeLines
1623    //-----------------------------------------------------------------------
1624    /**
1625     * Writes the <code>toString()</code> value of each item in a collection to
1626     * an <code>OutputStream</code> line by line, using the default character
1627     * encoding of the platform and the specified line ending.
1628     *
1629     * @param lines  the lines to write, null entries produce blank lines
1630     * @param lineEnding  the line separator to use, null is system default
1631     * @param output  the <code>OutputStream</code> to write to, not null, not closed
1632     * @throws NullPointerException if the output is null
1633     * @throws IOException if an I/O error occurs
1634     * @since 1.1
1635     */
1636    public static void writeLines(Collection<?> lines, String lineEnding,
1637            OutputStream output) throws IOException {
1638        writeLines(lines, lineEnding, output, Charset.defaultCharset());
1639    }
1640
1641    /**
1642     * Writes the <code>toString()</code> value of each item in a collection to
1643     * an <code>OutputStream</code> line by line, using the specified character
1644     * encoding and the specified line ending.
1645     *
1646     * @param lines  the lines to write, null entries produce blank lines
1647     * @param lineEnding  the line separator to use, null is system default
1648     * @param output  the <code>OutputStream</code> to write to, not null, not closed
1649     * @param encoding  the encoding to use, null means platform default
1650     * @throws NullPointerException if the output is null
1651     * @throws IOException if an I/O error occurs
1652     * @since 2.3
1653     */
1654    public static void writeLines(Collection<?> lines, String lineEnding, OutputStream output, Charset encoding)
1655            throws IOException {
1656        if (lines == null) {
1657            return;
1658        }
1659        if (lineEnding == null) {
1660            lineEnding = LINE_SEPARATOR;
1661        }
1662        Charset cs = Charsets.toCharset(encoding);
1663        for (Object line : lines) {
1664            if (line != null) {
1665                output.write(line.toString().getBytes(cs));
1666            }
1667            output.write(lineEnding.getBytes(cs));
1668        }
1669    }
1670
1671    /**
1672     * Writes the <code>toString()</code> value of each item in a collection to
1673     * an <code>OutputStream</code> line by line, using the specified character
1674     * encoding and the specified line ending.
1675     * <p>
1676     * Character encoding names can be found at
1677     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1678     *
1679     * @param lines  the lines to write, null entries produce blank lines
1680     * @param lineEnding  the line separator to use, null is system default
1681     * @param output  the <code>OutputStream</code> to write to, not null, not closed
1682     * @param encoding  the encoding to use, null means platform default
1683     * @throws NullPointerException if the output is null
1684     * @throws IOException if an I/O error occurs
1685     * @throws UnsupportedCharsetException
1686     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1687     *             supported.
1688     * @since 1.1
1689     */
1690    public static void writeLines(Collection<?> lines, String lineEnding,
1691            OutputStream output, String encoding) throws IOException {
1692        writeLines(lines, lineEnding, output, Charsets.toCharset(encoding));
1693    }
1694
1695    /**
1696     * Writes the <code>toString()</code> value of each item in a collection to
1697     * a <code>Writer</code> line by line, using the specified line ending.
1698     *
1699     * @param lines  the lines to write, null entries produce blank lines
1700     * @param lineEnding  the line separator to use, null is system default
1701     * @param writer  the <code>Writer</code> to write to, not null, not closed
1702     * @throws NullPointerException if the input is null
1703     * @throws IOException if an I/O error occurs
1704     * @since 1.1
1705     */
1706    public static void writeLines(Collection<?> lines, String lineEnding,
1707            Writer writer) throws IOException {
1708        if (lines == null) {
1709            return;
1710        }
1711        if (lineEnding == null) {
1712            lineEnding = LINE_SEPARATOR;
1713        }
1714        for (Object line : lines) {
1715            if (line != null) {
1716                writer.write(line.toString());
1717            }
1718            writer.write(lineEnding);
1719        }
1720    }
1721
1722    // copy from InputStream
1723    //-----------------------------------------------------------------------
1724    /**
1725     * Copy bytes from an <code>InputStream</code> to an
1726     * <code>OutputStream</code>.
1727     * <p>
1728     * This method buffers the input internally, so there is no need to use a
1729     * <code>BufferedInputStream</code>.
1730     * <p>
1731     * Large streams (over 2GB) will return a bytes copied value of
1732     * <code>-1</code> after the copy has completed since the correct
1733     * number of bytes cannot be returned as an int. For large streams
1734     * use the <code>copyLarge(InputStream, OutputStream)</code> method.
1735     * 
1736     * @param input  the <code>InputStream</code> to read from
1737     * @param output  the <code>OutputStream</code> to write to
1738     * @return the number of bytes copied, or -1 if &gt; Integer.MAX_VALUE
1739     * @throws NullPointerException if the input or output is null
1740     * @throws IOException if an I/O error occurs
1741     * @since 1.1
1742     */
1743    public static int copy(InputStream input, OutputStream output) throws IOException {
1744        long count = copyLarge(input, output);
1745        if (count > Integer.MAX_VALUE) {
1746            return -1;
1747        }
1748        return (int) count;
1749    }
1750
1751    /**
1752     * Copy bytes from a large (over 2GB) <code>InputStream</code> to an
1753     * <code>OutputStream</code>.
1754     * <p>
1755     * This method buffers the input internally, so there is no need to use a
1756     * <code>BufferedInputStream</code>.
1757     * <p>
1758     * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1759     * 
1760     * @param input  the <code>InputStream</code> to read from
1761     * @param output  the <code>OutputStream</code> to write to
1762     * @return the number of bytes copied
1763     * @throws NullPointerException if the input or output is null
1764     * @throws IOException if an I/O error occurs
1765     * @since 1.3
1766     */
1767    public static long copyLarge(InputStream input, OutputStream output)
1768            throws IOException {
1769        return copyLarge(input, output, new byte[DEFAULT_BUFFER_SIZE]);
1770    }
1771
1772    /**
1773     * Copy bytes from a large (over 2GB) <code>InputStream</code> to an
1774     * <code>OutputStream</code>.
1775     * <p>
1776     * This method uses the provided buffer, so there is no need to use a
1777     * <code>BufferedInputStream</code>.
1778     * <p>
1779     * 
1780     * @param input  the <code>InputStream</code> to read from
1781     * @param output  the <code>OutputStream</code> to write to
1782     * @param buffer the buffer to use for the copy
1783     * @return the number of bytes copied
1784     * @throws NullPointerException if the input or output is null
1785     * @throws IOException if an I/O error occurs
1786     * @since 2.2
1787     */
1788    public static long copyLarge(InputStream input, OutputStream output, byte[] buffer)
1789            throws IOException {
1790        long count = 0;
1791        int n = 0;
1792        while (EOF != (n = input.read(buffer))) {
1793            output.write(buffer, 0, n);
1794            count += n;
1795        }
1796        return count;
1797    }
1798
1799    /**
1800     * Copy some or all bytes from a large (over 2GB) <code>InputStream</code> to an
1801     * <code>OutputStream</code>, optionally skipping input bytes.
1802     * <p>
1803     * This method buffers the input internally, so there is no need to use a
1804     * <code>BufferedInputStream</code>.
1805     * <p>
1806     * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1807     * 
1808     * @param input  the <code>InputStream</code> to read from
1809     * @param output  the <code>OutputStream</code> to write to
1810     * @param inputOffset : number of bytes to skip from input before copying
1811     *         -ve values are ignored
1812     * @param length : number of bytes to copy. -ve means all
1813     * @return the number of bytes copied
1814     * @throws NullPointerException if the input or output is null
1815     * @throws IOException if an I/O error occurs
1816     * @since 2.2
1817     */
1818    public static long copyLarge(InputStream input, OutputStream output, long inputOffset, long length)
1819            throws IOException {
1820        return copyLarge(input, output, inputOffset, length, new byte[DEFAULT_BUFFER_SIZE]);
1821    }
1822
1823    /**
1824     * Copy some or all bytes from a large (over 2GB) <code>InputStream</code> to an
1825     * <code>OutputStream</code>, optionally skipping input bytes.
1826     * <p>
1827     * This method uses the provided buffer, so there is no need to use a
1828     * <code>BufferedInputStream</code>.
1829     * <p>
1830     * 
1831     * @param input  the <code>InputStream</code> to read from
1832     * @param output  the <code>OutputStream</code> to write to
1833     * @param inputOffset : number of bytes to skip from input before copying
1834     *         -ve values are ignored
1835     * @param length : number of bytes to copy. -ve means all
1836     * @param buffer the buffer to use for the copy
1837     *
1838     * @return the number of bytes copied
1839     * @throws NullPointerException if the input or output is null
1840     * @throws IOException if an I/O error occurs
1841     * @since 2.2
1842     */
1843    public static long copyLarge(InputStream input, OutputStream output, 
1844            final long inputOffset, final long length, byte[] buffer)  throws IOException {
1845        if (inputOffset > 0) {
1846            skipFully(input, inputOffset);
1847        }
1848        if (length == 0) {
1849            return 0;
1850        }
1851        final int bufferLength = buffer.length;
1852        int bytesToRead = bufferLength;
1853        if (length > 0 && length < bufferLength) {
1854            bytesToRead = (int) length;
1855        }
1856        int read;
1857        long totalRead = 0;
1858        while (bytesToRead > 0 && EOF != (read = input.read(buffer, 0, bytesToRead))) {
1859            output.write(buffer, 0, read);
1860            totalRead += read;
1861            if (length > 0) { // only adjust length if not reading to the end
1862                // Note the cast must work because buffer.length is an integer
1863                bytesToRead = (int) Math.min(length - totalRead, bufferLength);
1864            }
1865        }
1866        return totalRead;
1867    }
1868
1869    /**
1870     * Copy bytes from an <code>InputStream</code> to chars on a
1871     * <code>Writer</code> using the default character encoding of the platform.
1872     * <p>
1873     * This method buffers the input internally, so there is no need to use a
1874     * <code>BufferedInputStream</code>.
1875     * <p>
1876     * This method uses {@link InputStreamReader}.
1877     *
1878     * @param input  the <code>InputStream</code> to read from
1879     * @param output  the <code>Writer</code> to write to
1880     * @throws NullPointerException if the input or output is null
1881     * @throws IOException if an I/O error occurs
1882     * @since 1.1
1883     */
1884    public static void copy(InputStream input, Writer output)
1885            throws IOException {
1886        copy(input, output, Charset.defaultCharset());
1887    }
1888
1889    /**
1890     * Copy bytes from an <code>InputStream</code> to chars on a
1891     * <code>Writer</code> using the specified character encoding.
1892     * <p>
1893     * This method buffers the input internally, so there is no need to use a
1894     * <code>BufferedInputStream</code>.
1895     * <p>
1896     * This method uses {@link InputStreamReader}.
1897     *
1898     * @param input  the <code>InputStream</code> to read from
1899     * @param output  the <code>Writer</code> to write to
1900     * @param encoding  the encoding to use, null means platform default
1901     * @throws NullPointerException if the input or output is null
1902     * @throws IOException if an I/O error occurs
1903     * @since 2.3
1904     */
1905    public static void copy(InputStream input, Writer output, Charset encoding) throws IOException {
1906        InputStreamReader in = new InputStreamReader(input, Charsets.toCharset(encoding));
1907        copy(in, output);
1908    }
1909
1910    /**
1911     * Copy bytes from an <code>InputStream</code> to chars on a
1912     * <code>Writer</code> using the specified character encoding.
1913     * <p>
1914     * This method buffers the input internally, so there is no need to use a
1915     * <code>BufferedInputStream</code>.
1916     * <p>
1917     * Character encoding names can be found at
1918     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
1919     * <p>
1920     * This method uses {@link InputStreamReader}.
1921     *
1922     * @param input  the <code>InputStream</code> to read from
1923     * @param output  the <code>Writer</code> to write to
1924     * @param encoding  the encoding to use, null means platform default
1925     * @throws NullPointerException if the input or output is null
1926     * @throws IOException if an I/O error occurs
1927     * @throws UnsupportedCharsetException
1928     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
1929     *             supported.
1930     * @since 1.1
1931     */
1932    public static void copy(InputStream input, Writer output, String encoding) throws IOException {
1933        copy(input, output, Charsets.toCharset(encoding));
1934    }
1935
1936    // copy from Reader
1937    //-----------------------------------------------------------------------
1938    /**
1939     * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
1940     * <p>
1941     * This method buffers the input internally, so there is no need to use a
1942     * <code>BufferedReader</code>.
1943     * <p>
1944     * Large streams (over 2GB) will return a chars copied value of
1945     * <code>-1</code> after the copy has completed since the correct
1946     * number of chars cannot be returned as an int. For large streams
1947     * use the <code>copyLarge(Reader, Writer)</code> method.
1948     *
1949     * @param input  the <code>Reader</code> to read from
1950     * @param output  the <code>Writer</code> to write to
1951     * @return the number of characters copied, or -1 if &gt; Integer.MAX_VALUE
1952     * @throws NullPointerException if the input or output is null
1953     * @throws IOException if an I/O error occurs
1954     * @since 1.1
1955     */
1956    public static int copy(Reader input, Writer output) throws IOException {
1957        long count = copyLarge(input, output);
1958        if (count > Integer.MAX_VALUE) {
1959            return -1;
1960        }
1961        return (int) count;
1962    }
1963
1964    /**
1965     * Copy chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
1966     * <p>
1967     * This method buffers the input internally, so there is no need to use a
1968     * <code>BufferedReader</code>.
1969     * <p>
1970     * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1971     *
1972     * @param input  the <code>Reader</code> to read from
1973     * @param output  the <code>Writer</code> to write to
1974     * @return the number of characters copied
1975     * @throws NullPointerException if the input or output is null
1976     * @throws IOException if an I/O error occurs
1977     * @since 1.3
1978     */
1979    public static long copyLarge(Reader input, Writer output) throws IOException {
1980        return copyLarge(input, output, new char[DEFAULT_BUFFER_SIZE]);
1981    }
1982
1983    /**
1984     * Copy chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
1985     * <p>
1986     * This method uses the provided buffer, so there is no need to use a
1987     * <code>BufferedReader</code>.
1988     * <p>
1989     *
1990     * @param input  the <code>Reader</code> to read from
1991     * @param output  the <code>Writer</code> to write to
1992     * @param buffer the buffer to be used for the copy
1993     * @return the number of characters copied
1994     * @throws NullPointerException if the input or output is null
1995     * @throws IOException if an I/O error occurs
1996     * @since 2.2
1997     */
1998    public static long copyLarge(Reader input, Writer output, char [] buffer) throws IOException {
1999        long count = 0;
2000        int n = 0;
2001        while (EOF != (n = input.read(buffer))) {
2002            output.write(buffer, 0, n);
2003            count += n;
2004        }
2005        return count;
2006    }
2007
2008    /**
2009     * Copy some or all chars from a large (over 2GB) <code>InputStream</code> to an
2010     * <code>OutputStream</code>, optionally skipping input chars.
2011     * <p>
2012     * This method buffers the input internally, so there is no need to use a
2013     * <code>BufferedReader</code>.
2014     * <p>
2015     * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
2016     * 
2017     * @param input  the <code>Reader</code> to read from
2018     * @param output  the <code>Writer</code> to write to
2019     * @param inputOffset : number of chars to skip from input before copying
2020     *         -ve values are ignored
2021     * @param length : number of chars to copy. -ve means all
2022     * @return the number of chars copied
2023     * @throws NullPointerException if the input or output is null
2024     * @throws IOException if an I/O error occurs
2025     * @since 2.2
2026     */
2027    public static long copyLarge(Reader input, Writer output, final long inputOffset, final long length)
2028            throws IOException {
2029        return  copyLarge(input, output, inputOffset, length, new char[DEFAULT_BUFFER_SIZE]);
2030    }
2031
2032    /**
2033     * Copy some or all chars from a large (over 2GB) <code>InputStream</code> to an
2034     * <code>OutputStream</code>, optionally skipping input chars.
2035     * <p>
2036     * This method uses the provided buffer, so there is no need to use a
2037     * <code>BufferedReader</code>.
2038     * <p>
2039     * 
2040     * @param input  the <code>Reader</code> to read from
2041     * @param output  the <code>Writer</code> to write to
2042     * @param inputOffset : number of chars to skip from input before copying
2043     *         -ve values are ignored
2044     * @param length : number of chars to copy. -ve means all
2045     * @param buffer the buffer to be used for the copy
2046     * @return the number of chars copied
2047     * @throws NullPointerException if the input or output is null
2048     * @throws IOException if an I/O error occurs
2049     * @since 2.2
2050     */
2051    public static long copyLarge(Reader input, Writer output, final long inputOffset, final long length, char [] buffer)
2052            throws IOException {
2053        if (inputOffset > 0) {
2054            skipFully(input, inputOffset);
2055        }
2056        if (length == 0) {
2057            return 0;
2058        }
2059        int bytesToRead = buffer.length;
2060        if (length > 0 && length < buffer.length) {
2061            bytesToRead = (int) length;
2062        }
2063        int read;
2064        long totalRead = 0;
2065        while (bytesToRead > 0 && EOF != (read = input.read(buffer, 0, bytesToRead))) {
2066            output.write(buffer, 0, read);
2067            totalRead += read;
2068            if (length > 0) { // only adjust length if not reading to the end
2069                // Note the cast must work because buffer.length is an integer
2070                bytesToRead = (int) Math.min(length - totalRead, buffer.length);
2071            }
2072        }
2073        return totalRead;
2074    }
2075
2076    /**
2077     * Copy chars from a <code>Reader</code> to bytes on an
2078     * <code>OutputStream</code> using the default character encoding of the
2079     * platform, and calling flush.
2080     * <p>
2081     * This method buffers the input internally, so there is no need to use a
2082     * <code>BufferedReader</code>.
2083     * <p>
2084     * Due to the implementation of OutputStreamWriter, this method performs a
2085     * flush.
2086     * <p>
2087     * This method uses {@link OutputStreamWriter}.
2088     *
2089     * @param input  the <code>Reader</code> to read from
2090     * @param output  the <code>OutputStream</code> to write to
2091     * @throws NullPointerException if the input or output is null
2092     * @throws IOException if an I/O error occurs
2093     * @since 1.1
2094     */
2095    public static void copy(Reader input, OutputStream output)
2096            throws IOException {
2097        copy(input, output, Charset.defaultCharset());
2098    }
2099
2100    /**
2101     * Copy chars from a <code>Reader</code> to bytes on an
2102     * <code>OutputStream</code> using the specified character encoding, and
2103     * calling flush.
2104     * <p>
2105     * This method buffers the input internally, so there is no need to use a
2106     * <code>BufferedReader</code>.
2107     * </p>
2108     * <p>
2109     * Due to the implementation of OutputStreamWriter, this method performs a
2110     * flush.
2111     * </p>
2112     * <p>
2113     * This method uses {@link OutputStreamWriter}.
2114     * </p>
2115     *
2116     * @param input  the <code>Reader</code> to read from
2117     * @param output  the <code>OutputStream</code> to write to
2118     * @param encoding  the encoding to use, null means platform default
2119     * @throws NullPointerException if the input or output is null
2120     * @throws IOException if an I/O error occurs
2121     * @since 2.3
2122     */
2123    public static void copy(Reader input, OutputStream output, Charset encoding) throws IOException {
2124        OutputStreamWriter out = new OutputStreamWriter(output, Charsets.toCharset(encoding));
2125        copy(input, out);
2126        // XXX Unless anyone is planning on rewriting OutputStreamWriter,
2127        // we have to flush here.
2128        out.flush();
2129    }
2130
2131    /**
2132     * Copy chars from a <code>Reader</code> to bytes on an
2133     * <code>OutputStream</code> using the specified character encoding, and
2134     * calling flush.
2135     * <p>
2136     * This method buffers the input internally, so there is no need to use a
2137     * <code>BufferedReader</code>.
2138     * <p>
2139     * Character encoding names can be found at
2140     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
2141     * <p>
2142     * Due to the implementation of OutputStreamWriter, this method performs a
2143     * flush.
2144     * <p>
2145     * This method uses {@link OutputStreamWriter}.
2146     *
2147     * @param input  the <code>Reader</code> to read from
2148     * @param output  the <code>OutputStream</code> to write to
2149     * @param encoding  the encoding to use, null means platform default
2150     * @throws NullPointerException if the input or output is null
2151     * @throws IOException if an I/O error occurs
2152     * @throws UnsupportedCharsetException
2153     *             thrown instead of {@link UnsupportedEncodingException} in version 2.2 if the encoding is not
2154     *             supported.
2155     * @since 1.1
2156     */
2157    public static void copy(Reader input, OutputStream output, String encoding) throws IOException {
2158        copy(input, output, Charsets.toCharset(encoding));
2159    }
2160
2161    // content equals
2162    //-----------------------------------------------------------------------
2163    /**
2164     * Compare the contents of two Streams to determine if they are equal or
2165     * not.
2166     * <p>
2167     * This method buffers the input internally using
2168     * <code>BufferedInputStream</code> if they are not already buffered.
2169     *
2170     * @param input1  the first stream
2171     * @param input2  the second stream
2172     * @return true if the content of the streams are equal or they both don't
2173     * exist, false otherwise
2174     * @throws NullPointerException if either input is null
2175     * @throws IOException if an I/O error occurs
2176     */
2177    public static boolean contentEquals(InputStream input1, InputStream input2)
2178            throws IOException {
2179        if (!(input1 instanceof BufferedInputStream)) {
2180            input1 = new BufferedInputStream(input1);
2181        }
2182        if (!(input2 instanceof BufferedInputStream)) {
2183            input2 = new BufferedInputStream(input2);
2184        }
2185
2186        int ch = input1.read();
2187        while (EOF != ch) {
2188            int ch2 = input2.read();
2189            if (ch != ch2) {
2190                return false;
2191            }
2192            ch = input1.read();
2193        }
2194
2195        int ch2 = input2.read();
2196        return ch2 == EOF;
2197    }
2198
2199    /**
2200     * Compare the contents of two Readers to determine if they are equal or
2201     * not.
2202     * <p>
2203     * This method buffers the input internally using
2204     * <code>BufferedReader</code> if they are not already buffered.
2205     *
2206     * @param input1  the first reader
2207     * @param input2  the second reader
2208     * @return true if the content of the readers are equal or they both don't
2209     * exist, false otherwise
2210     * @throws NullPointerException if either input is null
2211     * @throws IOException if an I/O error occurs
2212     * @since 1.1
2213     */
2214    public static boolean contentEquals(Reader input1, Reader input2)
2215            throws IOException {
2216        
2217        input1 = toBufferedReader(input1);
2218        input2 = toBufferedReader(input2);
2219
2220        int ch = input1.read();
2221        while (EOF != ch) {
2222            int ch2 = input2.read();
2223            if (ch != ch2) {
2224                return false;
2225            }
2226            ch = input1.read();
2227        }
2228
2229        int ch2 = input2.read();
2230        return ch2 == EOF;
2231    }
2232
2233    /**
2234     * Compare the contents of two Readers to determine if they are equal or
2235     * not, ignoring EOL characters.
2236     * <p>
2237     * This method buffers the input internally using
2238     * <code>BufferedReader</code> if they are not already buffered.
2239     *
2240     * @param input1  the first reader
2241     * @param input2  the second reader
2242     * @return true if the content of the readers are equal (ignoring EOL differences),  false otherwise
2243     * @throws NullPointerException if either input is null
2244     * @throws IOException if an I/O error occurs
2245     * @since 2.2
2246     */
2247    public static boolean contentEqualsIgnoreEOL(Reader input1, Reader input2)
2248            throws IOException {
2249        BufferedReader br1 = toBufferedReader(input1);
2250        BufferedReader br2 = toBufferedReader(input2);
2251
2252        String line1 = br1.readLine();
2253        String line2 = br2.readLine();
2254        while (line1 != null && line2 != null && line1.equals(line2)) {
2255            line1 = br1.readLine();
2256            line2 = br2.readLine();
2257        }
2258        return line1 == null ? line2 == null ? true : false : line1.equals(line2);
2259    }
2260
2261    /**
2262     * Skip bytes from an input byte stream.
2263     * This implementation guarantees that it will read as many bytes
2264     * as possible before giving up; this may not always be the case for
2265     * subclasses of {@link Reader}.
2266     *   
2267     * @param input byte stream to skip
2268     * @param toSkip number of bytes to skip.
2269     * @return number of bytes actually skipped.
2270     * 
2271     * @see InputStream#skip(long)
2272     * 
2273     * @throws IOException if there is a problem reading the file
2274     * @throws IllegalArgumentException if toSkip is negative
2275     * @since 2.0
2276     */
2277    public static long skip(InputStream input, long toSkip) throws IOException {
2278        if (toSkip < 0) {
2279            throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
2280        }
2281        /*
2282         * N.B. no need to synchronize this because: - we don't care if the buffer is created multiple times (the data
2283         * is ignored) - we always use the same size buffer, so if it it is recreated it will still be OK (if the buffer
2284         * size were variable, we would need to synch. to ensure some other thread did not create a smaller one)
2285         */
2286        if (SKIP_BYTE_BUFFER == null) {
2287            SKIP_BYTE_BUFFER = new byte[SKIP_BUFFER_SIZE];
2288        }
2289        long remain = toSkip;
2290        while (remain > 0) {
2291            long n = input.read(SKIP_BYTE_BUFFER, 0, (int) Math.min(remain, SKIP_BUFFER_SIZE));
2292            if (n < 0) { // EOF
2293                break;
2294            }
2295            remain -= n;
2296        }
2297        return toSkip - remain;
2298    }
2299
2300    /**
2301     * Skip characters from an input character stream.
2302     * This implementation guarantees that it will read as many characters
2303     * as possible before giving up; this may not always be the case for
2304     * subclasses of {@link Reader}.
2305     *   
2306     * @param input character stream to skip
2307     * @param toSkip number of characters to skip.
2308     * @return number of characters actually skipped.
2309     * 
2310     * @see Reader#skip(long)
2311     * 
2312     * @throws IOException if there is a problem reading the file
2313     * @throws IllegalArgumentException if toSkip is negative
2314     * @since 2.0
2315     */
2316    public static long skip(Reader input, long toSkip) throws IOException {
2317        if (toSkip < 0) {
2318            throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
2319        }
2320        /*
2321         * N.B. no need to synchronize this because: - we don't care if the buffer is created multiple times (the data
2322         * is ignored) - we always use the same size buffer, so if it it is recreated it will still be OK (if the buffer
2323         * size were variable, we would need to synch. to ensure some other thread did not create a smaller one)
2324         */
2325        if (SKIP_CHAR_BUFFER == null) {
2326            SKIP_CHAR_BUFFER = new char[SKIP_BUFFER_SIZE];
2327        }
2328        long remain = toSkip;
2329        while (remain > 0) {
2330            long n = input.read(SKIP_CHAR_BUFFER, 0, (int) Math.min(remain, SKIP_BUFFER_SIZE));
2331            if (n < 0) { // EOF
2332                break;
2333            }
2334            remain -= n;
2335        }
2336        return toSkip - remain;
2337    }
2338
2339    /**
2340     * Skip the requested number of bytes or fail if there are not enough left.
2341     * <p>
2342     * This allows for the possibility that {@link InputStream#skip(long)} may
2343     * not skip as many bytes as requested (most likely because of reaching EOF).
2344     * 
2345     * @param input stream to skip
2346     * @param toSkip the number of bytes to skip
2347     * @see InputStream#skip(long)
2348     * 
2349     * @throws IOException if there is a problem reading the file
2350     * @throws IllegalArgumentException if toSkip is negative
2351     * @throws EOFException if the number of bytes skipped was incorrect 
2352     * @since 2.0
2353     */
2354    public static void skipFully(InputStream input, long toSkip) throws IOException {
2355        if (toSkip < 0) {
2356            throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip);
2357        }
2358        long skipped = skip(input, toSkip);
2359        if (skipped != toSkip) {
2360            throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped);
2361        }
2362    }
2363
2364    /**
2365     * Skip the requested number of characters or fail if there are not enough left.
2366     * <p>
2367     * This allows for the possibility that {@link Reader#skip(long)} may
2368     * not skip as many characters as requested (most likely because of reaching EOF).
2369     * 
2370     * @param input stream to skip
2371     * @param toSkip the number of characters to skip
2372     * @see Reader#skip(long)
2373     * 
2374     * @throws IOException if there is a problem reading the file
2375     * @throws IllegalArgumentException if toSkip is negative
2376     * @throws EOFException if the number of characters skipped was incorrect
2377     * @since 2.0
2378     */
2379    public static void skipFully(Reader input, long toSkip) throws IOException {
2380        long skipped = skip(input, toSkip);
2381        if (skipped != toSkip) {
2382            throw new EOFException("Chars to skip: " + toSkip + " actual: " + skipped);
2383        }
2384    }
2385    
2386
2387    /**
2388     * Read characters from an input character stream.
2389     * This implementation guarantees that it will read as many characters
2390     * as possible before giving up; this may not always be the case for
2391     * subclasses of {@link Reader}.
2392     * 
2393     * @param input where to read input from
2394     * @param buffer destination
2395     * @param offset inital offset into buffer
2396     * @param length length to read, must be >= 0
2397     * @return actual length read; may be less than requested if EOF was reached
2398     * @throws IOException if a read error occurs
2399     * @since 2.2
2400     */
2401    public static int read(Reader input, char[] buffer, int offset, int length) throws IOException {
2402        if (length < 0) {
2403            throw new IllegalArgumentException("Length must not be negative: " + length);
2404        }
2405        int remaining = length;
2406        while (remaining > 0) {
2407            int location = length - remaining;
2408            int count = input.read(buffer, offset + location, remaining);
2409            if (EOF == count) { // EOF
2410                break;
2411            }
2412            remaining -= count;
2413        }
2414        return length - remaining;
2415    }
2416
2417    /**
2418     * Read characters from an input character stream.
2419     * This implementation guarantees that it will read as many characters
2420     * as possible before giving up; this may not always be the case for
2421     * subclasses of {@link Reader}.
2422     * 
2423     * @param input where to read input from
2424     * @param buffer destination
2425     * @return actual length read; may be less than requested if EOF was reached
2426     * @throws IOException if a read error occurs
2427     * @since 2.2
2428     */
2429    public static int read(Reader input, char[] buffer) throws IOException {
2430        return read(input, buffer, 0, buffer.length);
2431    }
2432
2433    /**
2434     * Read bytes from an input stream.
2435     * This implementation guarantees that it will read as many bytes
2436     * as possible before giving up; this may not always be the case for
2437     * subclasses of {@link InputStream}.
2438     * 
2439     * @param input where to read input from
2440     * @param buffer destination
2441     * @param offset inital offset into buffer
2442     * @param length length to read, must be >= 0
2443     * @return actual length read; may be less than requested if EOF was reached
2444     * @throws IOException if a read error occurs
2445     * @since 2.2
2446     */
2447    public static int read(InputStream input, byte[] buffer, int offset, int length) throws IOException {
2448        if (length < 0) {
2449            throw new IllegalArgumentException("Length must not be negative: " + length);
2450        }
2451        int remaining = length;
2452        while (remaining > 0) {
2453            int location = length - remaining;
2454            int count = input.read(buffer, offset + location, remaining);
2455            if (EOF == count) { // EOF
2456                break;
2457            }
2458            remaining -= count;
2459        }
2460        return length - remaining;
2461    }
2462    
2463    /**
2464     * Read bytes from an input stream.
2465     * This implementation guarantees that it will read as many bytes
2466     * as possible before giving up; this may not always be the case for
2467     * subclasses of {@link InputStream}.
2468     * 
2469     * @param input where to read input from
2470     * @param buffer destination
2471     * @return actual length read; may be less than requested if EOF was reached
2472     * @throws IOException if a read error occurs
2473     * @since 2.2
2474     */
2475    public static int read(InputStream input, byte[] buffer) throws IOException {
2476        return read(input, buffer, 0, buffer.length);
2477    }
2478
2479    /**
2480     * Read the requested number of characters or fail if there are not enough left.
2481     * <p>
2482     * This allows for the possibility that {@link Reader#read(char[], int, int)} may
2483     * not read as many characters as requested (most likely because of reaching EOF).
2484     * 
2485     * @param input where to read input from
2486     * @param buffer destination
2487     * @param offset inital offset into buffer
2488     * @param length length to read, must be >= 0
2489     * 
2490     * @throws IOException if there is a problem reading the file
2491     * @throws IllegalArgumentException if length is negative
2492     * @throws EOFException if the number of characters read was incorrect
2493     * @since 2.2
2494     */
2495    public static void readFully(Reader input, char[] buffer, int offset, int length) throws IOException {
2496        int actual = read(input, buffer, offset, length);
2497        if (actual != length) {
2498            throw new EOFException("Length to read: " + length + " actual: " + actual);
2499        }
2500    }
2501
2502    /**
2503     * Read the requested number of characters or fail if there are not enough left.
2504     * <p>
2505     * This allows for the possibility that {@link Reader#read(char[], int, int)} may
2506     * not read as many characters as requested (most likely because of reaching EOF).
2507     * 
2508     * @param input where to read input from
2509     * @param buffer destination
2510     * 
2511     * @throws IOException if there is a problem reading the file
2512     * @throws IllegalArgumentException if length is negative
2513     * @throws EOFException if the number of characters read was incorrect
2514     * @since 2.2
2515     */
2516    public static void readFully(Reader input, char[] buffer) throws IOException {
2517        readFully(input, buffer, 0, buffer.length);
2518    }
2519
2520    /**
2521     * Read the requested number of bytes or fail if there are not enough left.
2522     * <p>
2523     * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
2524     * not read as many bytes as requested (most likely because of reaching EOF).
2525     * 
2526     * @param input where to read input from
2527     * @param buffer destination
2528     * @param offset inital offset into buffer
2529     * @param length length to read, must be >= 0
2530     * 
2531     * @throws IOException if there is a problem reading the file
2532     * @throws IllegalArgumentException if length is negative
2533     * @throws EOFException if the number of bytes read was incorrect
2534     * @since 2.2
2535     */
2536    public static void readFully(InputStream input, byte[] buffer, int offset, int length) throws IOException {
2537        int actual = read(input, buffer, offset, length);
2538        if (actual != length) {
2539            throw new EOFException("Length to read: " + length + " actual: " + actual);
2540        }
2541    }
2542
2543    /**
2544     * Read the requested number of bytes or fail if there are not enough left.
2545     * <p>
2546     * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
2547     * not read as many bytes as requested (most likely because of reaching EOF).
2548     * 
2549     * @param input where to read input from
2550     * @param buffer destination
2551     * 
2552     * @throws IOException if there is a problem reading the file
2553     * @throws IllegalArgumentException if length is negative
2554     * @throws EOFException if the number of bytes read was incorrect
2555     * @since 2.2
2556     */
2557    public static void readFully(InputStream input, byte[] buffer) throws IOException {
2558        readFully(input, buffer, 0, buffer.length);
2559    }
2560}