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