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: 1750548 $ $Date: 2016-06-28 19:32:21 +0200 (Tue, 28 Jun 2016) $ 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 {@code Channel} suppressing any {@code IOException}. 761 * <p> 762 * <b>Note:</b><br/>The usecase justifying this method is a shortcoming of the Java language up to but not including 763 * Java 7. For any code targetting Java 7 or later use of this method is highly discouraged and the 764 * {@code try-with-resources} statement should be used instead. Care must be taken to not use this method in a way 765 * {@code IOException}s get suppressed incorrectly. 766 * <strong>You must close all resources in use inside the {@code try} block to not suppress exceptions in the 767 * {@code finally} block incorrectly by using this method.</strong> 768 * </p> 769 * <p> 770 * <b>Example:</b><br/> 771 * <pre> 772 * // Introduce variables for the resources and initialize them to null. This cannot throw an exception. 773 * Closeable resource1 = null; 774 * Closeable resource2 = null; 775 * try 776 * { 777 * // Obtain a resource object and assign it to variable resource1. This may throw an exception. 778 * // If successful, resource1 != null. 779 * resource1 = ... 780 * 781 * // Obtain a resource object and assign it to variable resource2. This may throw an exception. 782 * // If successful, resource2 != null. Not reached if an exception has been thrown above. 783 * resource2 = ... 784 * 785 * // Perform operations on the resources. This may throw an exception. Not reached if an exception has been 786 * // thrown above. Note: Treat the variables resource1 and resource2 the same way as if they would have been 787 * // declared with the final modifier - that is - do NOT write anyting like resource1 = something else or 788 * // resource2 = something else here. 789 * resource1 ... 790 * resource2 ... 791 * 792 * // Finally, close the resources and set the variables to null indicating successful completion. 793 * // This may throw an exception. Not reached if an exception has been thrown above. 794 * resource1.close(); 795 * resource1 = null; 796 * // Not reached if an exception has been thrown above. 797 * resource2.close(); 798 * resource2 = null; 799 * 800 * // All resources are closed at this point and all operations (up to here) completed successfully without 801 * // throwing an exception we would need to handle (by letting it propagate or by catching and handling it). 802 * } 803 * finally 804 * { 805 * // Cleanup any resource not closed in the try block due to an exception having been thrown and suppress any 806 * // exception this may produce to not stop the exception from the try block to be propagated. If the try 807 * // block completed successfully, all variables will have been set to null there and this will not do 808 * // anything. This is just to cleanup properly in case of an exception. 809 * 810 * IOUtil.close( resource1 ); 811 * IOUtil.close( resource2 ); 812 * 813 * // Without that utility method you would need to write the following: 814 * // 815 * // try 816 * // { 817 * // if ( resource1 != null ) 818 * // { 819 * // resource1.close(); 820 * // } 821 * // } 822 * // catch( IOException e ) 823 * // { 824 * // Suppressed. If resource1 != null, an exception has already been thrown in the try block we need to 825 * // propagate instead of this one. 826 * // } 827 * // finally 828 * // { 829 * // try 830 * // { 831 * // if ( resource2 != null ) 832 * // { 833 * // resource2.close(); 834 * // } 835 * // } 836 * // catch ( IOException e ) 837 * // { 838 * // Suppressed. If resource2 != null, an exception has already been thrown in the try block we need to 839 * // propagate instead of this one. 840 * // } 841 * // } 842 * } 843 * </pre> 844 * </p> 845 * 846 * @param channel The channel to close or {@code null}. 847 */ 848 public static void close( @Nullable Channel channel ) 849 { 850 try 851 { 852 if ( channel != null ) 853 { 854 channel.close(); 855 } 856 } 857 catch ( IOException ex ) 858 { 859 // Suppressed 860 } 861 } 862 863 /** 864 * Closes an {@code InputStream} suppressing any {@code IOException}. 865 * <p> 866 * <b>Note:</b><br/>The usecase justifying this method is a shortcoming of the Java language up to but not including 867 * Java 7. For any code targeting Java 7 or later use of this method is highly discouraged and the 868 * {@code try-with-resources} statement should be used instead. Care must be taken to not use this method in a way 869 * {@code IOException}s get suppressed incorrectly. 870 * <strong>You must close all resources in use inside the {@code try} block to not suppress exceptions in the 871 * {@code finally} block incorrectly by using this method.</strong> 872 * </p> 873 * <p> 874 * <b>Example:</b><br/> 875 * <pre> 876 * // Introduce variables for the resources and initialize them to null. This cannot throw an exception. 877 * Closeable resource1 = null; 878 * Closeable resource2 = null; 879 * try 880 * { 881 * // Obtain a resource object and assign it to variable resource1. This may throw an exception. 882 * // If successful, resource1 != null. 883 * resource1 = ... 884 * 885 * // Obtain a resource object and assign it to variable resource2. This may throw an exception. 886 * // If successful, resource2 != null. Not reached if an exception has been thrown above. 887 * resource2 = ... 888 * 889 * // Perform operations on the resources. This may throw an exception. Not reached if an exception has been 890 * // thrown above. Note: Treat the variables resource1 and resource2 the same way as if they would have been 891 * // declared with the final modifier - that is - do NOT write anyting like resource1 = something else or 892 * // resource2 = something else here. 893 * resource1 ... 894 * resource2 ... 895 * 896 * // Finally, close the resources and set the variables to null indicating successful completion. 897 * // This may throw an exception. Not reached if an exception has been thrown above. 898 * resource1.close(); 899 * resource1 = null; 900 * // This may throw an exception. Not reached if an exception has been thrown above. 901 * resource2.close(); 902 * resource2 = null; 903 * 904 * // All resources are closed at this point and all operations (up to here) completed successfully without 905 * // throwing an exception we would need to handle (by letting it propagate or by catching and handling it). 906 * } 907 * finally 908 * { 909 * // Cleanup any resource not closed in the try block due to an exception having been thrown and suppress any 910 * // exception this may produce to not stop the exception from the try block to be propagated. If the try 911 * // block completed successfully, all variables will have been set to null there and this will not do 912 * // anything. This is just to cleanup properly in case of an exception. 913 * 914 * IOUtil.close( resource1 ); 915 * IOUtil.close( resource2 ); 916 * 917 * // Without that utility method you would need to write the following: 918 * // 919 * // try 920 * // { 921 * // if ( resource1 != null ) 922 * // { 923 * // resource1.close(); 924 * // } 925 * // } 926 * // catch( IOException e ) 927 * // { 928 * // Suppressed. If resource1 != null, an exception has already been thrown in the try block we need to 929 * // propagate instead of this one. 930 * // } 931 * // finally 932 * // { 933 * // try 934 * // { 935 * // if ( resource2 != null ) 936 * // { 937 * // resource2.close(); 938 * // } 939 * // } 940 * // catch ( IOException e ) 941 * // { 942 * // Suppressed. If resource2 != null, an exception has already been thrown in the try block we need to 943 * // propagate instead of this one. 944 * // } 945 * // } 946 * } 947 * </pre> 948 * </p> 949 * 950 * @param inputStream The stream to close or {@code null}. 951 */ 952 public static void close( @Nullable InputStream inputStream ) 953 { 954 try 955 { 956 if ( inputStream != null ) 957 { 958 inputStream.close(); 959 } 960 } 961 catch ( IOException ex ) 962 { 963 // Suppressed 964 } 965 } 966 967 /** 968 * Closes an {@code OutputStream} suppressing any {@code IOException}. 969 * <p> 970 * <b>Note:</b><br/>The usecase justifying this method is a shortcoming of the Java language up to but not including 971 * Java 7. For any code targeting Java 7 or later use of this method is highly discouraged and the 972 * {@code try-with-resources} statement should be used instead. Care must be taken to not use this method in a way 973 * {@code IOException}s get suppressed incorrectly. 974 * <strong>You must close all resources in use inside the {@code try} block to not suppress exceptions in the 975 * {@code finally} block incorrectly by using this method.</strong> 976 * </p> 977 * <p> 978 * <b>Example:</b><br/> 979 * <pre> 980 * // Introduce variables for the resources and initialize them to null. This cannot throw an exception. 981 * Closeable resource1 = null; 982 * Closeable resource2 = null; 983 * try 984 * { 985 * // Obtain a resource object and assign it to variable resource1. This may throw an exception. 986 * // If successful, resource1 != null. 987 * resource1 = ... 988 * 989 * // Obtain a resource object and assign it to variable resource2. This may throw an exception. 990 * // If successful, resource2 != null. Not reached if an exception has been thrown above. 991 * resource2 = ... 992 * 993 * // Perform operations on the resources. This may throw an exception. Not reached if an exception has been 994 * // thrown above. Note: Treat the variables resource1 and resource2 the same way as if they would have been 995 * // declared with the final modifier - that is - do NOT write anyting like resource1 = something else or 996 * // resource2 = something else here. 997 * resource1 ... 998 * resource2 ... 999 * 1000 * // Finally, close the resources and set the variables to null indicating successful completion. 1001 * // This may throw an exception. Not reached if an exception has been thrown above. 1002 * resource1.close(); 1003 * resource1 = null; 1004 * // This may throw an exception. Not reached if an exception has been thrown above. 1005 * resource2.close(); 1006 * resource2 = null; 1007 * 1008 * // All resources are closed at this point and all operations (up to here) completed successfully without 1009 * // throwing an exception we would need to handle (by letting it propagate or by catching and handling it). 1010 * } 1011 * finally 1012 * { 1013 * // Cleanup any resource not closed in the try block due to an exception having been thrown and suppress any 1014 * // exception this may produce to not stop the exception from the try block to be propagated. If the try 1015 * // block completed successfully, all variables will have been set to null there and this will not do 1016 * // anything. This is just to cleanup properly in case of an exception. 1017 * 1018 * IOUtil.close( resource1 ); 1019 * IOUtil.close( resource2 ); 1020 * 1021 * // Without that utility method you would need to write the following: 1022 * // 1023 * // try 1024 * // { 1025 * // if ( resource1 != null ) 1026 * // { 1027 * // resource1.close(); 1028 * // } 1029 * // } 1030 * // catch( IOException e ) 1031 * // { 1032 * // Suppressed. If resource1 != null, an exception has already been thrown in the try block we need to 1033 * // propagate instead of this one. 1034 * // } 1035 * // finally 1036 * // { 1037 * // try 1038 * // { 1039 * // if ( resource2 != null ) 1040 * // { 1041 * // resource2.close(); 1042 * // } 1043 * // } 1044 * // catch ( IOException e ) 1045 * // { 1046 * // Suppressed. If resource2 != null, an exception has already been thrown in the try block we need to 1047 * // propagate instead of this one. 1048 * // } 1049 * // } 1050 * } 1051 * </pre> 1052 * </p> 1053 * 1054 * @param outputStream The stream to close or {@code null}. 1055 */ 1056 public static void close( @Nullable OutputStream outputStream ) 1057 { 1058 try 1059 { 1060 if ( outputStream != null ) 1061 { 1062 outputStream.close(); 1063 } 1064 } 1065 catch ( IOException ex ) 1066 { 1067 // Suppressed 1068 } 1069 } 1070 1071 /** 1072 * Closes a {@code Reader} suppressing any {@code IOException}. 1073 * <p> 1074 * <b>Note:</b><br/>The usecase justifying this method is a shortcoming of the Java language up to but not including 1075 * Java 7. For any code targeting Java 7 or later use of this method is highly discouraged and the 1076 * {@code try-with-resources} statement should be used instead. Care must be taken to not use this method in a way 1077 * {@code IOException}s get suppressed incorrectly. 1078 * <strong>You must close all resources in use inside the {@code try} block to not suppress exceptions in the 1079 * {@code finally} block incorrectly by using this method.</strong> 1080 * </p> 1081 * <p> 1082 * <b>Example:</b><br/> 1083 * <pre> 1084 * // Introduce variables for the resources and initialize them to null. This cannot throw an exception. 1085 * Closeable resource1 = null; 1086 * Closeable resource2 = null; 1087 * try 1088 * { 1089 * // Obtain a resource object and assign it to variable resource1. This may throw an exception. 1090 * // If successful, resource1 != null. 1091 * resource1 = ... 1092 * 1093 * // Obtain a resource object and assign it to variable resource2. This may throw an exception. 1094 * // If successful, resource2 != null. Not reached if an exception has been thrown above. 1095 * resource2 = ... 1096 * 1097 * // Perform operations on the resources. This may throw an exception. Not reached if an exception has been 1098 * // thrown above. Note: Treat the variables resource1 and resource2 the same way as if they would have been 1099 * // declared with the final modifier - that is - do NOT write anyting like resource1 = something else or 1100 * // resource2 = something else here. 1101 * resource1 ... 1102 * resource2 ... 1103 * 1104 * // Finally, close the resources and set the variables to null indicating successful completion. 1105 * // This may throw an exception. Not reached if an exception has been thrown above. 1106 * resource1.close(); 1107 * resource1 = null; 1108 * // This may throw an exception. Not reached if an exception has been thrown above. 1109 * resource2.close(); 1110 * resource2 = null; 1111 * 1112 * // All resources are closed at this point and all operations (up to here) completed successfully without 1113 * // throwing an exception we would need to handle (by letting it propagate or by catching and handling it). 1114 * } 1115 * finally 1116 * { 1117 * // Cleanup any resource not closed in the try block due to an exception having been thrown and suppress any 1118 * // exception this may produce to not stop the exception from the try block to be propagated. If the try 1119 * // block completed successfully, all variables will have been set to null there and this will not do 1120 * // anything. This is just to cleanup properly in case of an exception. 1121 * 1122 * IOUtil.close( resource1 ); 1123 * IOUtil.close( resource2 ); 1124 * 1125 * // Without that utility method you would need to write the following: 1126 * // 1127 * // try 1128 * // { 1129 * // if ( resource1 != null ) 1130 * // { 1131 * // resource1.close(); 1132 * // } 1133 * // } 1134 * // catch( IOException e ) 1135 * // { 1136 * // Suppressed. If resource1 != null, an exception has already been thrown in the try block we need to 1137 * // propagate instead of this one. 1138 * // } 1139 * // finally 1140 * // { 1141 * // try 1142 * // { 1143 * // if ( resource2 != null ) 1144 * // { 1145 * // resource2.close(); 1146 * // } 1147 * // } 1148 * // catch ( IOException e ) 1149 * // { 1150 * // Suppressed. If resource2 != null, an exception has already been thrown in the try block we need to 1151 * // propagate instead of this one. 1152 * // } 1153 * // } 1154 * } 1155 * </pre> 1156 * </p> 1157 * 1158 * @param reader The reader to close or {@code null}. 1159 */ 1160 public static void close( @Nullable Reader reader ) 1161 { 1162 try 1163 { 1164 if ( reader != null ) 1165 { 1166 reader.close(); 1167 } 1168 } 1169 catch ( IOException ex ) 1170 { 1171 // Suppressed 1172 } 1173 } 1174 1175 /** 1176 * Closes a {@code Writer} suppressing any {@code IOException}. 1177 * <p> 1178 * <b>Note:</b><br/>The usecase justifying this method is a shortcoming of the Java language up to but not including 1179 * Java 7. For any code targeting Java 7 or later use of this method is highly discouraged and the 1180 * {@code try-with-resources} statement should be used instead. Care must be taken to not use this method in a way 1181 * {@code IOException}s get suppressed incorrectly. 1182 * <strong>You must close all resources in use inside the {@code try} block to not suppress exceptions in the 1183 * {@code finally} block incorrectly by using this method.</strong> 1184 * </p> 1185 * <p> 1186 * <b>Example:</b><br/> 1187 * <pre> 1188 * // Introduce variables for the resources and initialize them to null. This cannot throw an exception. 1189 * Closeable resource1 = null; 1190 * Closeable resource2 = null; 1191 * try 1192 * { 1193 * // Obtain a resource object and assign it to variable resource1. This may throw an exception. 1194 * // If successful, resource1 != null. 1195 * resource1 = ... 1196 * 1197 * // Obtain a resource object and assign it to variable resource2. This may throw an exception. 1198 * // If successful, resource2 != null. Not reached if an exception has been thrown above. 1199 * resource2 = ... 1200 * 1201 * // Perform operations on the resources. This may throw an exception. Not reached if an exception has been 1202 * // thrown above. Note: Treat the variables resource1 and resource2 the same way as if they would have been 1203 * // declared with the final modifier - that is - do NOT write anyting like resource1 = something else or 1204 * // resource2 = something else here. 1205 * resource1 ... 1206 * resource2 ... 1207 * 1208 * // Finally, close the resources and set the variables to null indicating successful completion. 1209 * // This may throw an exception. Not reached if an exception has been thrown above. 1210 * resource1.close(); 1211 * resource1 = null; 1212 * // This may throw an exception. Not reached if an exception has been thrown above. 1213 * resource2.close(); 1214 * resource2 = null; 1215 * 1216 * // All resources are closed at this point and all operations (up to here) completed successfully without 1217 * // throwing an exception we would need to handle (by letting it propagate or by catching and handling it). 1218 * } 1219 * finally 1220 * { 1221 * // Cleanup any resource not closed in the try block due to an exception having been thrown and suppress any 1222 * // exception this may produce to not stop the exception from the try block to be propagated. If the try 1223 * // block completed successfully, all variables will have been set to null there and this will not do 1224 * // anything. This is just to cleanup properly in case of an exception. 1225 * 1226 * IOUtil.close( resource1 ); 1227 * IOUtil.close( resource2 ); 1228 * 1229 * // Without that utility method you would need to write the following: 1230 * // 1231 * // try 1232 * // { 1233 * // if ( resource1 != null ) 1234 * // { 1235 * // resource1.close(); 1236 * // } 1237 * // } 1238 * // catch( IOException e ) 1239 * // { 1240 * // Suppressed. If resource1 != null, an exception has already been thrown in the try block we need to 1241 * // propagate instead of this one. 1242 * // } 1243 * // finally 1244 * // { 1245 * // try 1246 * // { 1247 * // if ( resource2 != null ) 1248 * // { 1249 * // resource2.close(); 1250 * // } 1251 * // } 1252 * // catch ( IOException e ) 1253 * // { 1254 * // Suppressed. If resource2 != null, an exception has already been thrown in the try block we need to 1255 * // propagate instead of this one. 1256 * // } 1257 * // } 1258 * } 1259 * </pre> 1260 * </p> 1261 * 1262 * @param writer The writer to close or {@code null}. 1263 */ 1264 public static void close( @Nullable Writer writer ) 1265 { 1266 try 1267 { 1268 if ( writer != null ) 1269 { 1270 writer.close(); 1271 } 1272 } 1273 catch ( IOException ex ) 1274 { 1275 // Suppressed 1276 } 1277 } 1278 }