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