1 package org.apache.maven.it.util; 2 3 /* ==================================================================== 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 2001 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, 22 * if any, must include the following acknowledgment: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowledgment may appear in the software itself, 26 * if and wherever such third-party acknowledgments normally appear. 27 * 28 * 4. The names "Apache" and "Apache Software Foundation" and 29 * "Apache Turbine" must not be used to endorse or promote products 30 * derived from this software without prior written permission. For 31 * written permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache", 34 * "Apache Turbine", nor may "Apache" appear in their name, without 35 * prior written permission of the Apache Software Foundation. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>. 55 */ 56 57 import java.io.BufferedInputStream; 58 import java.io.BufferedOutputStream; 59 import java.io.ByteArrayInputStream; 60 import java.io.ByteArrayOutputStream; 61 import java.io.IOException; 62 import java.io.InputStream; 63 import java.io.InputStreamReader; 64 import java.io.OutputStream; 65 import java.io.OutputStreamWriter; 66 import java.io.Reader; 67 import java.io.StringReader; 68 import java.io.StringWriter; 69 import java.io.Writer; 70 71 /** 72 * General IO Stream manipulation. 73 * <p> 74 * This class provides static utility methods for input/output operations, particularly buffered 75 * copying between sources (<code>InputStream</code>, <code>Reader</code>, <code>String</code> and 76 * <code>byte[]</code>) and destinations (<code>OutputStream</code>, <code>Writer</code>, 77 * <code>String</code> and <code>byte[]</code>). 78 * </p> 79 * 80 * <p>Unless otherwise noted, these <code>copy</code> methods do <em>not</em> flush or close the 81 * streams. Often, doing so would require making non-portable assumptions about the streams' origin 82 * and further use. This means that both streams' <code>close()</code> methods must be called after 83 * copying. if one omits this step, then the stream resources (sockets, file descriptors) are 84 * released when the associated Stream is garbage-collected. It is not a good idea to rely on this 85 * mechanism. For a good overview of the distinction between "memory management" and "resource 86 * management", see <a href="http://www.unixreview.com/articles/1998/9804/9804ja/ja.htm">this 87 * UnixReview article</a></p> 88 * 89 * <p>For each <code>copy</code> method, a variant is provided that allows the caller to specify the 90 * buffer size (the default is 4k). As the buffer size can have a fairly large impact on speed, this 91 * may be worth tweaking. Often "large buffer -> faster" does not hold, even for large data 92 * transfers.</p> 93 * 94 * <p>For byte-to-char methods, a <code>copy</code> variant allows the encoding to be selected 95 * (otherwise the platform default is used).</p> 96 * 97 * <p>The <code>copy</code> methods use an internal buffer when copying. It is therefore advisable 98 * <em>not</em> to deliberately wrap the stream arguments to the <code>copy</code> methods in 99 * <code>Buffered*</code> streams. For example, don't do the 100 * following:</p> 101 * 102 * <code>copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) );</code> 103 * 104 * <p>The rationale is as follows:</p> 105 * 106 * <p>Imagine that an InputStream's read() is a very expensive operation, which would usually suggest 107 * wrapping in a BufferedInputStream. The BufferedInputStream works by issuing infrequent 108 * {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the underlying InputStream, to 109 * fill an internal buffer, from which further <code>read</code> requests can inexpensively get 110 * their data (until the buffer runs out).</p> 111 * <p>However, the <code>copy</code> methods do the same thing, keeping an internal buffer, 112 * populated by {@link InputStream#read(byte[] b, int off, int len)} requests. Having two buffers 113 * (or three if the destination stream is also buffered) is pointless, and the unnecessary buffer 114 * management hurts performance slightly (about 3%, according to some simple experiments).</p> 115 * 116 * @author <a href="mailto:peter@apache.org">Peter Donald</a> 117 * @author <a href="mailto:jefft@apache.org">Jeff Turner</a> 118 * @version CVS $Revision: 661727 $ $Date: 2008-05-30 16:21:49 +0200 (fr., 30 mai 2008) $ 119 * @since 4.0 120 */ 121 122 /* 123 * Behold, intrepid explorers; a map of this class: 124 * 125 * Method Input Output Dependency 126 * ------ ----- ------ ------- 127 * 1 copy InputStream OutputStream (primitive) 128 * 2 copy Reader Writer (primitive) 129 * 130 * 3 copy InputStream Writer 2 131 * 4 toString InputStream String 3 132 * 5 toByteArray InputStream byte[] 1 133 * 134 * 6 copy Reader OutputStream 2 135 * 7 toString Reader String 2 136 * 8 toByteArray Reader byte[] 6 137 * 138 * 9 copy String OutputStream 2 139 * 10 copy String Writer (trivial) 140 * 11 toByteArray String byte[] 9 141 * 142 * 12 copy byte[] Writer 3 143 * 13 toString byte[] String 12 144 * 14 copy byte[] OutputStream (trivial) 145 * 146 * 147 * Note that only the first two methods shuffle bytes; the rest use these two, or (if possible) copy 148 * using native Java copy methods. As there are method variants to specify buffer size and encoding, 149 * each row may correspond to up to 4 methods. 150 * 151 */ 152 153 public final class IOUtil 154 { 155 private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; 156 157 /** 158 * Private constructor to prevent instantiation. 159 */ 160 private IOUtil() 161 { 162 } 163 164 /////////////////////////////////////////////////////////////// 165 // Core copy methods 166 /////////////////////////////////////////////////////////////// 167 168 /** 169 * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>. 170 */ 171 public static void copy( final InputStream input, final OutputStream output ) 172 throws IOException 173 { 174 copy( input, output, DEFAULT_BUFFER_SIZE ); 175 } 176 177 /** 178 * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>. 179 * @param bufferSize Size of internal buffer to use. 180 */ 181 public static void copy( final InputStream input, 182 final OutputStream output, 183 final int bufferSize ) 184 throws IOException 185 { 186 final byte[] buffer = new byte[bufferSize]; 187 int n = 0; 188 while ( -1 != ( n = input.read( buffer ) ) ) 189 { 190 output.write( buffer, 0, n ); 191 } 192 } 193 194 /** 195 * Copy chars from a <code>Reader</code> to a <code>Writer</code>. 196 */ 197 public static void copy( final Reader input, final Writer output ) 198 throws IOException 199 { 200 copy( input, output, DEFAULT_BUFFER_SIZE ); 201 } 202 203 /** 204 * Copy chars from a <code>Reader</code> to a <code>Writer</code>. 205 * @param bufferSize Size of internal buffer to use. 206 */ 207 public static void copy( final Reader input, final Writer output, final int bufferSize ) 208 throws IOException 209 { 210 final char[] buffer = new char[bufferSize]; 211 int n = 0; 212 while ( -1 != ( n = input.read( buffer ) ) ) 213 { 214 output.write( buffer, 0, n ); 215 } 216 output.flush(); 217 } 218 219 /////////////////////////////////////////////////////////////// 220 // Derived copy methods 221 // InputStream -> * 222 /////////////////////////////////////////////////////////////// 223 224 225 /////////////////////////////////////////////////////////////// 226 // InputStream -> Writer 227 228 /** 229 * Copy and convert bytes from an <code>InputStream</code> to chars on a 230 * <code>Writer</code>. 231 * The platform's default encoding is used for the byte-to-char conversion. 232 */ 233 public static void copy( final InputStream input, final Writer output ) 234 throws IOException 235 { 236 copy( input, output, DEFAULT_BUFFER_SIZE ); 237 } 238 239 /** 240 * Copy and convert bytes from an <code>InputStream</code> to chars on a 241 * <code>Writer</code>. 242 * The platform's default encoding is used for the byte-to-char conversion. 243 * @param bufferSize Size of internal buffer to use. 244 */ 245 public static void copy( final InputStream input, final Writer output, final int bufferSize ) 246 throws IOException 247 { 248 final InputStreamReader in = new InputStreamReader( input ); 249 copy( in, output, bufferSize ); 250 } 251 252 /** 253 * Copy and convert bytes from an <code>InputStream</code> to chars on a 254 * <code>Writer</code>, using the specified encoding. 255 * @param encoding The name of a supported character encoding. See the 256 * <a href="http://www.iana.org/assignments/character-sets">IANA 257 * Charset Registry</a> for a list of valid encoding types. 258 */ 259 public static void copy( final InputStream input, final Writer output, final String encoding ) 260 throws IOException 261 { 262 final InputStreamReader in = new InputStreamReader( input, encoding ); 263 copy( in, output ); 264 } 265 266 /** 267 * Copy and convert bytes from an <code>InputStream</code> to chars on a 268 * <code>Writer</code>, using the specified encoding. 269 * @param encoding The name of a supported character encoding. See the 270 * <a href="http://www.iana.org/assignments/character-sets">IANA 271 * Charset Registry</a> for a list of valid encoding types. 272 * @param bufferSize Size of internal buffer to use. 273 */ 274 public static void copy( final InputStream input, 275 final Writer output, 276 final String encoding, 277 final int bufferSize ) 278 throws IOException 279 { 280 final InputStreamReader in = new InputStreamReader( input, encoding ); 281 copy( in, output, bufferSize ); 282 } 283 284 285 /////////////////////////////////////////////////////////////// 286 // InputStream -> String 287 288 /** 289 * Get the contents of an <code>InputStream</code> as a String. 290 * The platform's default encoding is used for the byte-to-char conversion. 291 */ 292 public static String toString( final InputStream input ) 293 throws IOException 294 { 295 return toString( input, DEFAULT_BUFFER_SIZE ); 296 } 297 298 /** 299 * Get the contents of an <code>InputStream</code> as a String. 300 * The platform's default encoding is used for the byte-to-char conversion. 301 * @param bufferSize Size of internal buffer to use. 302 */ 303 public static String toString( final InputStream input, final int bufferSize ) 304 throws IOException 305 { 306 final StringWriter sw = new StringWriter(); 307 copy( input, sw, bufferSize ); 308 return sw.toString(); 309 } 310 311 /** 312 * Get the contents of an <code>InputStream</code> as a String. 313 * @param encoding The name of a supported character encoding. See the 314 * <a href="http://www.iana.org/assignments/character-sets">IANA 315 * Charset Registry</a> for a list of valid encoding types. 316 */ 317 public static String toString( final InputStream input, final String encoding ) 318 throws IOException 319 { 320 return toString( input, encoding, DEFAULT_BUFFER_SIZE ); 321 } 322 323 /** 324 * Get the contents of an <code>InputStream</code> as a String. 325 * @param encoding The name of a supported character encoding. See the 326 * <a href="http://www.iana.org/assignments/character-sets">IANA 327 * Charset Registry</a> for a list of valid encoding types. 328 * @param bufferSize Size of internal buffer to use. 329 */ 330 public static String toString( final InputStream input, 331 final String encoding, 332 final int bufferSize ) 333 throws IOException 334 { 335 final StringWriter sw = new StringWriter(); 336 copy( input, sw, encoding, bufferSize ); 337 return sw.toString(); 338 } 339 340 /////////////////////////////////////////////////////////////// 341 // InputStream -> byte[] 342 343 /** 344 * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>. 345 */ 346 public static byte[] toByteArray( final InputStream input ) 347 throws IOException 348 { 349 return toByteArray( input, DEFAULT_BUFFER_SIZE ); 350 } 351 352 /** 353 * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>. 354 * @param bufferSize Size of internal buffer to use. 355 */ 356 public static byte[] toByteArray( final InputStream input, final int bufferSize ) 357 throws IOException 358 { 359 final ByteArrayOutputStream output = new ByteArrayOutputStream(); 360 copy( input, output, bufferSize ); 361 return output.toByteArray(); 362 } 363 364 365 /////////////////////////////////////////////////////////////// 366 // Derived copy methods 367 // Reader -> * 368 /////////////////////////////////////////////////////////////// 369 370 /////////////////////////////////////////////////////////////// 371 // Reader -> OutputStream 372 /** 373 * Serialize chars from a <code>Reader</code> to bytes on an <code>OutputStream</code>, and 374 * flush the <code>OutputStream</code>. 375 */ 376 public static void copy( final Reader input, final OutputStream output ) 377 throws IOException 378 { 379 copy( input, output, DEFAULT_BUFFER_SIZE ); 380 } 381 382 /** 383 * Serialize chars from a <code>Reader</code> to bytes on an <code>OutputStream</code>, and 384 * flush the <code>OutputStream</code>. 385 * @param bufferSize Size of internal buffer to use. 386 */ 387 public static void copy( final Reader input, final OutputStream output, final int bufferSize ) 388 throws IOException 389 { 390 final OutputStreamWriter out = new OutputStreamWriter( output ); 391 copy( input, out, bufferSize ); 392 // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush 393 // here. 394 out.flush(); 395 } 396 397 /////////////////////////////////////////////////////////////// 398 // Reader -> String 399 /** 400 * Get the contents of a <code>Reader</code> as a String. 401 */ 402 public static String toString( final Reader input ) 403 throws IOException 404 { 405 return toString( input, DEFAULT_BUFFER_SIZE ); 406 } 407 408 /** 409 * Get the contents of a <code>Reader</code> as a String. 410 * @param bufferSize Size of internal buffer to use. 411 */ 412 public static String toString( final Reader input, final int bufferSize ) 413 throws IOException 414 { 415 final StringWriter sw = new StringWriter(); 416 copy( input, sw, bufferSize ); 417 return sw.toString(); 418 } 419 420 421 /////////////////////////////////////////////////////////////// 422 // Reader -> byte[] 423 /** 424 * Get the contents of a <code>Reader</code> as a <code>byte[]</code>. 425 */ 426 public static byte[] toByteArray( final Reader input ) 427 throws IOException 428 { 429 return toByteArray( input, DEFAULT_BUFFER_SIZE ); 430 } 431 432 /** 433 * Get the contents of a <code>Reader</code> as a <code>byte[]</code>. 434 * @param bufferSize Size of internal buffer to use. 435 */ 436 public static byte[] toByteArray( final Reader input, final int bufferSize ) 437 throws IOException 438 { 439 ByteArrayOutputStream output = new ByteArrayOutputStream(); 440 copy( input, output, bufferSize ); 441 return output.toByteArray(); 442 } 443 444 445 /////////////////////////////////////////////////////////////// 446 // Derived copy methods 447 // String -> * 448 /////////////////////////////////////////////////////////////// 449 450 451 /////////////////////////////////////////////////////////////// 452 // String -> OutputStream 453 454 /** 455 * Serialize chars from a <code>String</code> to bytes on an <code>OutputStream</code>, and 456 * flush the <code>OutputStream</code>. 457 */ 458 public static void copy( final String input, final OutputStream output ) 459 throws IOException 460 { 461 copy( input, output, DEFAULT_BUFFER_SIZE ); 462 } 463 464 /** 465 * Serialize chars from a <code>String</code> to bytes on an <code>OutputStream</code>, and 466 * flush the <code>OutputStream</code>. 467 * @param bufferSize Size of internal buffer to use. 468 */ 469 public static void copy( final String input, final OutputStream output, final int bufferSize ) 470 throws IOException 471 { 472 final StringReader in = new StringReader( input ); 473 final OutputStreamWriter out = new OutputStreamWriter( output ); 474 copy( in, out, bufferSize ); 475 // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush 476 // here. 477 out.flush(); 478 } 479 480 481 482 /////////////////////////////////////////////////////////////// 483 // String -> Writer 484 485 /** 486 * Copy chars from a <code>String</code> to a <code>Writer</code>. 487 */ 488 public static void copy( final String input, final Writer output ) 489 throws IOException 490 { 491 output.write( input ); 492 } 493 494 /** 495 * Copy bytes from an <code>InputStream</code> to an 496 * <code>OutputStream</code>, with buffering. 497 * This is equivalent to passing a 498 * {@link java.io.BufferedInputStream} and 499 * {@link java.io.BufferedOutputStream} to {@link #copy(InputStream, OutputStream)}, 500 * and flushing the output stream afterwards. The streams are not closed 501 * after the copy. 502 * @deprecated Buffering streams is actively harmful! See the class description as to why. Use 503 * {@link #copy(InputStream, OutputStream)} instead. 504 */ 505 public static void bufferedCopy( final InputStream input, final OutputStream output ) 506 throws IOException 507 { 508 final BufferedInputStream in = new BufferedInputStream( input ); 509 final BufferedOutputStream out = new BufferedOutputStream( output ); 510 copy( in, out ); 511 out.flush(); 512 } 513 514 515 /////////////////////////////////////////////////////////////// 516 // String -> byte[] 517 /** 518 * Get the contents of a <code>String</code> as a <code>byte[]</code>. 519 */ 520 public static byte[] toByteArray( final String input ) 521 throws IOException 522 { 523 return toByteArray( input, DEFAULT_BUFFER_SIZE ); 524 } 525 526 /** 527 * Get the contents of a <code>String</code> as a <code>byte[]</code>. 528 * @param bufferSize Size of internal buffer to use. 529 */ 530 public static byte[] toByteArray( final String input, final int bufferSize ) 531 throws IOException 532 { 533 ByteArrayOutputStream output = new ByteArrayOutputStream(); 534 copy( input, output, bufferSize ); 535 return output.toByteArray(); 536 } 537 538 539 540 /////////////////////////////////////////////////////////////// 541 // Derived copy methods 542 // byte[] -> * 543 /////////////////////////////////////////////////////////////// 544 545 546 /////////////////////////////////////////////////////////////// 547 // byte[] -> Writer 548 549 /** 550 * Copy and convert bytes from a <code>byte[]</code> to chars on a 551 * <code>Writer</code>. 552 * The platform's default encoding is used for the byte-to-char conversion. 553 */ 554 public static void copy( final byte[] input, final Writer output ) 555 throws IOException 556 { 557 copy( input, output, DEFAULT_BUFFER_SIZE ); 558 } 559 560 /** 561 * Copy and convert bytes from a <code>byte[]</code> to chars on a 562 * <code>Writer</code>. 563 * The platform's default encoding is used for the byte-to-char conversion. 564 * @param bufferSize Size of internal buffer to use. 565 */ 566 public static void copy( final byte[] input, final Writer output, final int bufferSize ) 567 throws IOException 568 { 569 final ByteArrayInputStream in = new ByteArrayInputStream( input ); 570 copy( in, output, bufferSize ); 571 } 572 573 /** 574 * Copy and convert bytes from a <code>byte[]</code> to chars on a 575 * <code>Writer</code>, using the specified encoding. 576 * @param encoding The name of a supported character encoding. See the 577 * <a href="http://www.iana.org/assignments/character-sets">IANA 578 * Charset Registry</a> for a list of valid encoding types. 579 */ 580 public static void copy( final byte[] input, final Writer output, final String encoding ) 581 throws IOException 582 { 583 final ByteArrayInputStream in = new ByteArrayInputStream( input ); 584 copy( in, output, encoding ); 585 } 586 587 /** 588 * Copy and convert bytes from a <code>byte[]</code> to chars on a 589 * <code>Writer</code>, using the specified encoding. 590 * @param encoding The name of a supported character encoding. See the 591 * <a href="http://www.iana.org/assignments/character-sets">IANA 592 * Charset Registry</a> for a list of valid encoding types. 593 * @param bufferSize Size of internal buffer to use. 594 */ 595 public static void copy( final byte[] input, 596 final Writer output, 597 final String encoding, 598 final int bufferSize ) 599 throws IOException 600 { 601 final ByteArrayInputStream in = new ByteArrayInputStream( input ); 602 copy( in, output, encoding, bufferSize ); 603 } 604 605 606 /////////////////////////////////////////////////////////////// 607 // byte[] -> String 608 609 /** 610 * Get the contents of a <code>byte[]</code> as a String. 611 * The platform's default encoding is used for the byte-to-char conversion. 612 */ 613 public static String toString( final byte[] input ) 614 throws IOException 615 { 616 return toString( input, DEFAULT_BUFFER_SIZE ); 617 } 618 619 /** 620 * Get the contents of a <code>byte[]</code> as a String. 621 * The platform's default encoding is used for the byte-to-char conversion. 622 * @param bufferSize Size of internal buffer to use. 623 */ 624 public static String toString( final byte[] input, final int bufferSize ) 625 throws IOException 626 { 627 final StringWriter sw = new StringWriter(); 628 copy( input, sw, bufferSize ); 629 return sw.toString(); 630 } 631 632 /** 633 * Get the contents of a <code>byte[]</code> as a String. 634 * @param encoding The name of a supported character encoding. See the 635 * <a href="http://www.iana.org/assignments/character-sets">IANA 636 * Charset Registry</a> for a list of valid encoding types. 637 */ 638 public static String toString( final byte[] input, final String encoding ) 639 throws IOException 640 { 641 return toString( input, encoding, DEFAULT_BUFFER_SIZE ); 642 } 643 644 /** 645 * Get the contents of a <code>byte[]</code> as a String. 646 * @param encoding The name of a supported character encoding. See the 647 * <a href="http://www.iana.org/assignments/character-sets">IANA 648 * Charset Registry</a> for a list of valid encoding types. 649 * @param bufferSize Size of internal buffer to use. 650 */ 651 public static String toString( final byte[] input, 652 final String encoding, 653 final int bufferSize ) 654 throws IOException 655 { 656 final StringWriter sw = new StringWriter(); 657 copy( input, sw, encoding, bufferSize ); 658 return sw.toString(); 659 } 660 661 662 /////////////////////////////////////////////////////////////// 663 // byte[] -> OutputStream 664 665 /** 666 * Copy bytes from a <code>byte[]</code> to an <code>OutputStream</code>. 667 */ 668 public static void copy( final byte[] input, final OutputStream output ) 669 throws IOException 670 { 671 copy( input, output, DEFAULT_BUFFER_SIZE ); 672 } 673 674 /** 675 * Copy bytes from a <code>byte[]</code> to an <code>OutputStream</code>. 676 * @param bufferSize Size of internal buffer to use. 677 */ 678 public static void copy( final byte[] input, 679 final OutputStream output, 680 final int bufferSize ) 681 throws IOException 682 { 683 output.write( input ); 684 } 685 686 /** 687 * Compare the contents of two Streams to determine if they are equal or not. 688 * 689 * @param input1 the first stream 690 * @param input2 the second stream 691 * @return true if the content of the streams are equal or they both don't exist, false otherwise 692 */ 693 public static boolean contentEquals( final InputStream input1, 694 final InputStream input2 ) 695 throws IOException 696 { 697 final InputStream bufferedInput1 = new BufferedInputStream( input1 ); 698 final InputStream bufferedInput2 = new BufferedInputStream( input2 ); 699 700 int ch = bufferedInput1.read(); 701 while ( -1 != ch ) 702 { 703 final int ch2 = bufferedInput2.read(); 704 if ( ch != ch2 ) 705 { 706 return false; 707 } 708 ch = bufferedInput1.read(); 709 } 710 711 final int ch2 = bufferedInput2.read(); 712 if ( -1 != ch2 ) 713 { 714 return false; 715 } 716 else 717 { 718 return true; 719 } 720 } 721 722 // ---------------------------------------------------------------------- 723 // closeXXX() 724 // ---------------------------------------------------------------------- 725 726 /** 727 * Closes the input stream. The input stream can be null and any IOException's will be swallowed. 728 * 729 * @param inputStream The stream to close. 730 */ 731 public static void close( InputStream inputStream ) 732 { 733 if ( inputStream == null ) 734 { 735 return; 736 } 737 738 try 739 { 740 inputStream.close(); 741 } 742 catch( IOException ex ) 743 { 744 // ignore 745 } 746 } 747 748 /** 749 * Closes the output stream. The output stream can be null and any IOException's will be swallowed. 750 * 751 * @param outputStream The stream to close. 752 */ 753 public static void close( OutputStream outputStream ) 754 { 755 if ( outputStream == null ) 756 { 757 return; 758 } 759 760 try 761 { 762 outputStream.close(); 763 } 764 catch( IOException ex ) 765 { 766 // ignore 767 } 768 } 769 770 /** 771 * Closes the reader. The reader can be null and any IOException's will be swallowed. 772 * 773 * @param reader The reader to close. 774 */ 775 public static void close( Reader reader ) 776 { 777 if ( reader == null ) 778 { 779 return; 780 } 781 782 try 783 { 784 reader.close(); 785 } 786 catch( IOException ex ) 787 { 788 // ignore 789 } 790 } 791 792 /** 793 * Closes the writer. The writer can be null and any IOException's will be swallowed. 794 * 795 * @param wrtier The writer to close. 796 */ 797 public static void close( Writer writer ) 798 { 799 if ( writer == null ) 800 { 801 return; 802 } 803 804 try 805 { 806 writer.close(); 807 } 808 catch( IOException ex ) 809 { 810 // ignore 811 } 812 } 813 }