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     */
017    package org.apache.commons.io;
018    
019    import java.io.BufferedInputStream;
020    import java.io.BufferedReader;
021    import java.io.ByteArrayInputStream;
022    import java.io.CharArrayWriter;
023    import java.io.Closeable;
024    import java.io.EOFException;
025    import java.io.File;
026    import java.io.IOException;
027    import java.io.InputStream;
028    import java.io.InputStreamReader;
029    import java.io.OutputStream;
030    import java.io.OutputStreamWriter;
031    import java.io.PrintWriter;
032    import java.io.Reader;
033    import java.io.UnsupportedEncodingException;
034    import java.io.Writer;
035    import java.net.HttpURLConnection;
036    import java.net.ServerSocket;
037    import java.net.Socket;
038    import java.net.URI;
039    import java.net.URL;
040    import java.net.URLConnection;
041    import java.nio.channels.Selector;
042    import java.nio.charset.Charset;
043    import java.nio.charset.UnsupportedCharsetException;
044    import java.util.ArrayList;
045    import java.util.Collection;
046    import java.util.List;
047    
048    import org.apache.commons.io.output.ByteArrayOutputStream;
049    import 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     */
084    public 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    }