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 > 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 > 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 }