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