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