1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.tika.io; 18 19 import java.io.BufferedInputStream; 20 import java.io.BufferedReader; 21 import java.io.ByteArrayInputStream; 22 import java.io.CharArrayWriter; 23 import java.io.IOException; 24 import java.io.InputStream; 25 import java.io.InputStreamReader; 26 import java.io.OutputStream; 27 import java.io.OutputStreamWriter; 28 import java.io.Reader; 29 import java.io.StringWriter; 30 import java.io.Writer; 31 import java.nio.channels.Channel; 32 import java.util.ArrayList; 33 import java.util.List; 34 35 /** 36 * General IO stream manipulation utilities. 37 * <p> 38 * This class provides static utility methods for input/output operations. 39 * <ul> 40 * <li>closeQuietly - these methods close a stream ignoring nulls and exceptions 41 * <li>toXxx/read - these methods read data from a stream 42 * <li>write - these methods write data to a stream 43 * <li>copy - these methods copy all the data from one stream to another 44 * <li>contentEquals - these methods compare the content of two streams 45 * </ul> 46 * <p> 47 * The byte-to-char methods and char-to-byte methods involve a conversion step. 48 * Two methods are provided in each case, one that uses the platform default 49 * encoding and the other which allows you to specify an encoding. You are 50 * encouraged to always specify an encoding because relying on the platform 51 * default can lead to unexpected results, for example when moving from 52 * development to production. 53 * <p> 54 * All the methods in this class that read a stream are buffered internally. 55 * This means that there is no cause to use a <code>BufferedInputStream</code> 56 * or <code>BufferedReader</code>. The default buffer size of 4K has been shown 57 * to be efficient in tests. 58 * <p> 59 * Wherever possible, the methods in this class do <em>not</em> flush or close 60 * the stream. This is to avoid making non-portable assumptions about the 61 * streams' origin and further use. Thus the caller is still responsible for 62 * closing streams after use. 63 * <p> 64 * Origin of code: Excalibur. 65 * 66 * @author Peter Donald 67 * @author Jeff Turner 68 * @author Matthew Hawthorne 69 * @author Stephen Colebourne 70 * @author Gareth Davis 71 * @author Ian Springer 72 * @author Niall Pemberton 73 * @author Sandy McArthur 74 * @since Apache Tika 0.4, copied (partially) from Commons IO 1.4 75 */ 76 public class IOUtils { 77 78 /** 79 * The default buffer size to use. 80 */ 81 private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; 82 83 /** 84 * Instances should NOT be constructed in standard programming. 85 */ 86 public IOUtils() { 87 super(); 88 } 89 90 //----------------------------------------------------------------------- 91 /** 92 * Unconditionally close an <code>Reader</code>. 93 * <p> 94 * Equivalent to {@link Reader#close()}, except any exceptions will be ignored. 95 * This is typically used in finally blocks. 96 * 97 * @param input the Reader to close, may be null or already closed 98 */ 99 public static void closeQuietly(Reader input) { 100 try { 101 if (input != null) { 102 input.close(); 103 } 104 } catch (IOException ioe) { 105 // ignore 106 } 107 } 108 109 /** 110 * Unconditionally close a <code>Channel</code>. 111 * <p> 112 * Equivalent to {@link Channel#close()}, except any exceptions will be ignored. 113 * This is typically used in finally blocks. 114 * 115 * @param channel the Channel to close, may be null or already closed 116 */ 117 public static void closeQuietly(Channel channel) { 118 try { 119 if (channel != null) { 120 channel.close(); 121 } 122 } catch (IOException ioe) { 123 // ignore 124 } 125 } 126 127 /** 128 * Unconditionally close a <code>Writer</code>. 129 * <p> 130 * Equivalent to {@link Writer#close()}, except any exceptions will be ignored. 131 * This is typically used in finally blocks. 132 * 133 * @param output the Writer to close, may be null or already closed 134 */ 135 public static void closeQuietly(Writer output) { 136 try { 137 if (output != null) { 138 output.close(); 139 } 140 } catch (IOException ioe) { 141 // ignore 142 } 143 } 144 145 /** 146 * Unconditionally close an <code>InputStream</code>. 147 * <p> 148 * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored. 149 * This is typically used in finally blocks. 150 * 151 * @param input the InputStream to close, may be null or already closed 152 */ 153 public static void closeQuietly(InputStream input) { 154 try { 155 if (input != null) { 156 input.close(); 157 } 158 } catch (IOException ioe) { 159 // ignore 160 } 161 } 162 163 /** 164 * Unconditionally close an <code>OutputStream</code>. 165 * <p> 166 * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored. 167 * This is typically used in finally blocks. 168 * 169 * @param output the OutputStream to close, may be null or already closed 170 */ 171 public static void closeQuietly(OutputStream output) { 172 try { 173 if (output != null) { 174 output.close(); 175 } 176 } catch (IOException ioe) { 177 // ignore 178 } 179 } 180 181 /** 182 * Fetches entire contents of an <code>InputStream</code> and represent 183 * same data as result InputStream. 184 * <p> 185 * This method is useful where, 186 * <ul> 187 * <li>Source InputStream is slow.</li> 188 * <li>It has network resources associated, so we cannot keep it open for 189 * long time.</li> 190 * <li>It has network timeout associated.</li> 191 * </ul> 192 * It can be used in favor of {@link #toByteArray(InputStream)}, since it 193 * avoids unnecessary allocation and copy of byte[].<br> 194 * This method buffers the input internally, so there is no need to use a 195 * <code>BufferedInputStream</code>. 196 * 197 * @param input Stream to be fully buffered. 198 * @return A fully buffered stream. 199 * @throws IOException if an I/O error occurs 200 * @since Commons IO 2.0 201 */ 202 public static InputStream toBufferedInputStream(InputStream input) throws IOException { 203 return ByteArrayOutputStream.toBufferedInputStream(input); 204 } 205 206 // read toByteArray 207 //----------------------------------------------------------------------- 208 /** 209 * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>. 210 * <p> 211 * This method buffers the input internally, so there is no need to use a 212 * <code>BufferedInputStream</code>. 213 * 214 * @param input the <code>InputStream</code> to read from 215 * @return the requested byte array 216 * @throws NullPointerException if the input is null 217 * @throws IOException if an I/O error occurs 218 */ 219 public static byte[] toByteArray(InputStream input) throws IOException { 220 ByteArrayOutputStream output = new ByteArrayOutputStream(); 221 copy(input, output); 222 return output.toByteArray(); 223 } 224 225 /** 226 * Get the contents of a <code>Reader</code> as a <code>byte[]</code> 227 * using the default character encoding of the platform. 228 * <p> 229 * This method buffers the input internally, so there is no need to use a 230 * <code>BufferedReader</code>. 231 * 232 * @param input the <code>Reader</code> to read from 233 * @return the requested byte array 234 * @throws NullPointerException if the input is null 235 * @throws IOException if an I/O error occurs 236 */ 237 public static byte[] toByteArray(Reader input) throws IOException { 238 ByteArrayOutputStream output = new ByteArrayOutputStream(); 239 copy(input, output); 240 return output.toByteArray(); 241 } 242 243 /** 244 * Get the contents of a <code>Reader</code> as a <code>byte[]</code> 245 * using the specified character encoding. 246 * <p> 247 * Character encoding names can be found at 248 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 249 * <p> 250 * This method buffers the input internally, so there is no need to use a 251 * <code>BufferedReader</code>. 252 * 253 * @param input the <code>Reader</code> to read from 254 * @param encoding the encoding to use, null means platform default 255 * @return the requested byte array 256 * @throws NullPointerException if the input is null 257 * @throws IOException if an I/O error occurs 258 * @since Commons IO 1.1 259 */ 260 public static byte[] toByteArray(Reader input, String encoding) 261 throws IOException { 262 ByteArrayOutputStream output = new ByteArrayOutputStream(); 263 copy(input, output, encoding); 264 return output.toByteArray(); 265 } 266 267 /** 268 * Get the contents of a <code>String</code> as a <code>byte[]</code> 269 * using the default character encoding of the platform. 270 * <p> 271 * This is the same as {@link String#getBytes()}. 272 * 273 * @param input the <code>String</code> to convert 274 * @return the requested byte array 275 * @throws NullPointerException if the input is null 276 * @throws IOException if an I/O error occurs (never occurs) 277 * @deprecated Use {@link String#getBytes()} 278 */ 279 @Deprecated 280 public static byte[] toByteArray(String input) throws IOException { 281 return input.getBytes(); 282 } 283 284 // read char[] 285 //----------------------------------------------------------------------- 286 /** 287 * Get the contents of an <code>InputStream</code> as a character array 288 * using the default character encoding of the platform. 289 * <p> 290 * This method buffers the input internally, so there is no need to use a 291 * <code>BufferedInputStream</code>. 292 * 293 * @param is the <code>InputStream</code> to read from 294 * @return the requested character array 295 * @throws NullPointerException if the input is null 296 * @throws IOException if an I/O error occurs 297 * @since Commons IO 1.1 298 */ 299 public static char[] toCharArray(InputStream is) throws IOException { 300 CharArrayWriter output = new CharArrayWriter(); 301 copy(is, output); 302 return output.toCharArray(); 303 } 304 305 /** 306 * Get the contents of an <code>InputStream</code> as a character array 307 * using the specified character encoding. 308 * <p> 309 * Character encoding names can be found at 310 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 311 * <p> 312 * This method buffers the input internally, so there is no need to use a 313 * <code>BufferedInputStream</code>. 314 * 315 * @param is the <code>InputStream</code> to read from 316 * @param encoding the encoding to use, null means platform default 317 * @return the requested character array 318 * @throws NullPointerException if the input is null 319 * @throws IOException if an I/O error occurs 320 * @since Commons IO 1.1 321 */ 322 public static char[] toCharArray(InputStream is, String encoding) 323 throws IOException { 324 CharArrayWriter output = new CharArrayWriter(); 325 copy(is, output, encoding); 326 return output.toCharArray(); 327 } 328 329 /** 330 * Get the contents of a <code>Reader</code> as a character array. 331 * <p> 332 * This method buffers the input internally, so there is no need to use a 333 * <code>BufferedReader</code>. 334 * 335 * @param input the <code>Reader</code> to read from 336 * @return the requested character array 337 * @throws NullPointerException if the input is null 338 * @throws IOException if an I/O error occurs 339 * @since Commons IO 1.1 340 */ 341 public static char[] toCharArray(Reader input) throws IOException { 342 CharArrayWriter sw = new CharArrayWriter(); 343 copy(input, sw); 344 return sw.toCharArray(); 345 } 346 347 // read toString 348 //----------------------------------------------------------------------- 349 /** 350 * Get the contents of an <code>InputStream</code> as a String 351 * using the default character encoding of the platform. 352 * <p> 353 * This method buffers the input internally, so there is no need to use a 354 * <code>BufferedInputStream</code>. 355 * 356 * @param input the <code>InputStream</code> to read from 357 * @return the requested String 358 * @throws NullPointerException if the input is null 359 * @throws IOException if an I/O error occurs 360 */ 361 public static String toString(InputStream input) throws IOException { 362 StringWriter sw = new StringWriter(); 363 copy(input, sw); 364 return sw.toString(); 365 } 366 367 /** 368 * Get the contents of an <code>InputStream</code> as a String 369 * using the specified character encoding. 370 * <p> 371 * Character encoding names can be found at 372 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 373 * <p> 374 * This method buffers the input internally, so there is no need to use a 375 * <code>BufferedInputStream</code>. 376 * 377 * @param input the <code>InputStream</code> to read from 378 * @param encoding the encoding to use, null means platform default 379 * @return the requested String 380 * @throws NullPointerException if the input is null 381 * @throws IOException if an I/O error occurs 382 */ 383 public static String toString(InputStream input, String encoding) 384 throws IOException { 385 StringWriter sw = new StringWriter(); 386 copy(input, sw, encoding); 387 return sw.toString(); 388 } 389 390 /** 391 * Get the contents of a <code>Reader</code> as a String. 392 * <p> 393 * This method buffers the input internally, so there is no need to use a 394 * <code>BufferedReader</code>. 395 * 396 * @param input the <code>Reader</code> to read from 397 * @return the requested String 398 * @throws NullPointerException if the input is null 399 * @throws IOException if an I/O error occurs 400 */ 401 public static String toString(Reader input) throws IOException { 402 StringWriter sw = new StringWriter(); 403 copy(input, sw); 404 return sw.toString(); 405 } 406 407 /** 408 * Get the contents of a <code>byte[]</code> as a String 409 * using the default character encoding of the platform. 410 * 411 * @param input the byte array to read from 412 * @return the requested String 413 * @throws NullPointerException if the input is null 414 * @throws IOException if an I/O error occurs (never occurs) 415 * @deprecated Use {@link String#String(byte[])} 416 */ 417 @Deprecated 418 public static String toString(byte[] input) throws IOException { 419 return new String(input); 420 } 421 422 /** 423 * Get the contents of a <code>byte[]</code> as a String 424 * using the specified character encoding. 425 * <p> 426 * Character encoding names can be found at 427 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 428 * 429 * @param input the byte array to read from 430 * @param encoding the encoding to use, null means platform default 431 * @return the requested String 432 * @throws NullPointerException if the input is null 433 * @throws IOException if an I/O error occurs (never occurs) 434 * @deprecated Use {@link String#String(byte[],String)} 435 */ 436 @Deprecated 437 public static String toString(byte[] input, String encoding) 438 throws IOException { 439 if (encoding == null) { 440 return new String(input); 441 } else { 442 return new String(input, encoding); 443 } 444 } 445 446 // readLines 447 //----------------------------------------------------------------------- 448 /** 449 * Get the contents of an <code>InputStream</code> as a list of Strings, 450 * one entry per line, using the default character encoding of the platform. 451 * <p> 452 * This method buffers the input internally, so there is no need to use a 453 * <code>BufferedInputStream</code>. 454 * 455 * @param input the <code>InputStream</code> to read from, not null 456 * @return the list of Strings, never null 457 * @throws NullPointerException if the input is null 458 * @throws IOException if an I/O error occurs 459 * @since Commons IO 1.1 460 */ 461 public static List<String> readLines(InputStream input) throws IOException { 462 InputStreamReader reader = new InputStreamReader(input); 463 return readLines(reader); 464 } 465 466 /** 467 * Get the contents of an <code>InputStream</code> as a list of Strings, 468 * one entry per line, using the specified character encoding. 469 * <p> 470 * Character encoding names can be found at 471 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 472 * <p> 473 * This method buffers the input internally, so there is no need to use a 474 * <code>BufferedInputStream</code>. 475 * 476 * @param input the <code>InputStream</code> to read from, not null 477 * @param encoding the encoding to use, null means platform default 478 * @return the list of Strings, never null 479 * @throws NullPointerException if the input is null 480 * @throws IOException if an I/O error occurs 481 * @since Commons IO 1.1 482 */ 483 public static List<String> readLines(InputStream input, String encoding) throws IOException { 484 if (encoding == null) { 485 return readLines(input); 486 } else { 487 InputStreamReader reader = new InputStreamReader(input, encoding); 488 return readLines(reader); 489 } 490 } 491 492 /** 493 * Get the contents of a <code>Reader</code> as a list of Strings, 494 * one entry per line. 495 * <p> 496 * This method buffers the input internally, so there is no need to use a 497 * <code>BufferedReader</code>. 498 * 499 * @param input the <code>Reader</code> to read from, not null 500 * @return the list of Strings, never null 501 * @throws NullPointerException if the input is null 502 * @throws IOException if an I/O error occurs 503 * @since Commons IO 1.1 504 */ 505 public static List<String> readLines(Reader input) throws IOException { 506 BufferedReader reader = new BufferedReader(input); 507 List<String> list = new ArrayList<String>(); 508 String line = reader.readLine(); 509 while (line != null) { 510 list.add(line); 511 line = reader.readLine(); 512 } 513 return list; 514 } 515 516 //----------------------------------------------------------------------- 517 /** 518 * Convert the specified CharSequence to an input stream, encoded as bytes 519 * using the default character encoding of the platform. 520 * 521 * @param input the CharSequence to convert 522 * @return an input stream 523 * @since IO 2.0 524 */ 525 public static InputStream toInputStream(CharSequence input) { 526 return toInputStream(input.toString()); 527 } 528 529 /** 530 * Convert the specified CharSequence to an input stream, encoded as bytes 531 * using the specified character encoding. 532 * <p> 533 * Character encoding names can be found at 534 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 535 * 536 * @param input the CharSequence to convert 537 * @param encoding the encoding to use, null means platform default 538 * @throws IOException if the encoding is invalid 539 * @return an input stream 540 * @since IO 2.0 541 */ 542 public static InputStream toInputStream(CharSequence input, String encoding) throws IOException { 543 return toInputStream(input.toString(), encoding); 544 } 545 546 //----------------------------------------------------------------------- 547 /** 548 * Convert the specified string to an input stream, encoded as bytes 549 * using the default character encoding of the platform. 550 * 551 * @param input the string to convert 552 * @return an input stream 553 * @since Commons IO 1.1 554 */ 555 public static InputStream toInputStream(String input) { 556 byte[] bytes = input.getBytes(); 557 return new ByteArrayInputStream(bytes); 558 } 559 560 /** 561 * Convert the specified string to an input stream, encoded as bytes 562 * using the specified character encoding. 563 * <p> 564 * Character encoding names can be found at 565 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 566 * 567 * @param input the string to convert 568 * @param encoding the encoding to use, null means platform default 569 * @throws IOException if the encoding is invalid 570 * @return an input stream 571 * @since Commons IO 1.1 572 */ 573 public static InputStream toInputStream(String input, String encoding) throws IOException { 574 byte[] bytes = encoding != null ? input.getBytes(encoding) : input.getBytes(); 575 return new ByteArrayInputStream(bytes); 576 } 577 578 // write byte[] 579 //----------------------------------------------------------------------- 580 /** 581 * Writes bytes from a <code>byte[]</code> to an <code>OutputStream</code>. 582 * 583 * @param data the byte array to write, do not modify during output, 584 * null ignored 585 * @param output the <code>OutputStream</code> to write to 586 * @throws NullPointerException if output is null 587 * @throws IOException if an I/O error occurs 588 * @since Commons IO 1.1 589 */ 590 public static void write(byte[] data, OutputStream output) 591 throws IOException { 592 if (data != null) { 593 output.write(data); 594 } 595 } 596 597 /** 598 * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code> 599 * using the default character encoding of the platform. 600 * <p> 601 * This method uses {@link String#String(byte[])}. 602 * 603 * @param data the byte array to write, do not modify during output, 604 * null ignored 605 * @param output the <code>Writer</code> to write to 606 * @throws NullPointerException if output is null 607 * @throws IOException if an I/O error occurs 608 * @since Commons IO 1.1 609 */ 610 public static void write(byte[] data, Writer output) throws IOException { 611 if (data != null) { 612 output.write(new String(data)); 613 } 614 } 615 616 /** 617 * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code> 618 * using the specified character encoding. 619 * <p> 620 * Character encoding names can be found at 621 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 622 * <p> 623 * This method uses {@link String#String(byte[], String)}. 624 * 625 * @param data the byte array to write, do not modify during output, 626 * null ignored 627 * @param output the <code>Writer</code> to write to 628 * @param encoding the encoding to use, null means platform default 629 * @throws NullPointerException if output is null 630 * @throws IOException if an I/O error occurs 631 * @since Commons IO 1.1 632 */ 633 public static void write(byte[] data, Writer output, String encoding) 634 throws IOException { 635 if (data != null) { 636 if (encoding == null) { 637 write(data, output); 638 } else { 639 output.write(new String(data, encoding)); 640 } 641 } 642 } 643 644 // write char[] 645 //----------------------------------------------------------------------- 646 /** 647 * Writes chars from a <code>char[]</code> to a <code>Writer</code> 648 * using the default character encoding of the platform. 649 * 650 * @param data the char array to write, do not modify during output, 651 * null ignored 652 * @param output the <code>Writer</code> to write to 653 * @throws NullPointerException if output is null 654 * @throws IOException if an I/O error occurs 655 * @since Commons IO 1.1 656 */ 657 public static void write(char[] data, Writer output) throws IOException { 658 if (data != null) { 659 output.write(data); 660 } 661 } 662 663 /** 664 * Writes chars from a <code>char[]</code> to bytes on an 665 * <code>OutputStream</code>. 666 * <p> 667 * This method uses {@link String#String(char[])} and 668 * {@link String#getBytes()}. 669 * 670 * @param data the char array to write, do not modify during output, 671 * null ignored 672 * @param output the <code>OutputStream</code> to write to 673 * @throws NullPointerException if output is null 674 * @throws IOException if an I/O error occurs 675 * @since Commons IO 1.1 676 */ 677 public static void write(char[] data, OutputStream output) 678 throws IOException { 679 if (data != null) { 680 output.write(new String(data).getBytes()); 681 } 682 } 683 684 /** 685 * Writes chars from a <code>char[]</code> to bytes on an 686 * <code>OutputStream</code> using the specified character encoding. 687 * <p> 688 * Character encoding names can be found at 689 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 690 * <p> 691 * This method uses {@link String#String(char[])} and 692 * {@link String#getBytes(String)}. 693 * 694 * @param data the char array to write, do not modify during output, 695 * null ignored 696 * @param output the <code>OutputStream</code> to write to 697 * @param encoding the encoding to use, null means platform default 698 * @throws NullPointerException if output is null 699 * @throws IOException if an I/O error occurs 700 * @since Commons IO 1.1 701 */ 702 public static void write(char[] data, OutputStream output, String encoding) 703 throws IOException { 704 if (data != null) { 705 if (encoding == null) { 706 write(data, output); 707 } else { 708 output.write(new String(data).getBytes(encoding)); 709 } 710 } 711 } 712 713 // write CharSequence 714 //----------------------------------------------------------------------- 715 /** 716 * Writes chars from a <code>CharSequence</code> to a <code>Writer</code>. 717 * 718 * @param data the <code>CharSequence</code> to write, null ignored 719 * @param output the <code>Writer</code> to write to 720 * @throws NullPointerException if output is null 721 * @throws IOException if an I/O error occurs 722 * @since Commons IO 2.0 723 */ 724 public static void write(CharSequence data, Writer output) throws IOException { 725 if (data != null) { 726 write(data.toString(), output); 727 } 728 } 729 730 /** 731 * Writes chars from a <code>CharSequence</code> to bytes on an 732 * <code>OutputStream</code> using the default character encoding of the 733 * platform. 734 * <p> 735 * This method uses {@link String#getBytes()}. 736 * 737 * @param data the <code>CharSequence</code> to write, null ignored 738 * @param output the <code>OutputStream</code> to write to 739 * @throws NullPointerException if output is null 740 * @throws IOException if an I/O error occurs 741 * @since Commons IO 2.0 742 */ 743 public static void write(CharSequence data, OutputStream output) 744 throws IOException { 745 if (data != null) { 746 write(data.toString(), output); 747 } 748 } 749 750 /** 751 * Writes chars from a <code>CharSequence</code> to bytes on an 752 * <code>OutputStream</code> using the specified character encoding. 753 * <p> 754 * Character encoding names can be found at 755 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 756 * <p> 757 * This method uses {@link String#getBytes(String)}. 758 * 759 * @param data the <code>CharSequence</code> to write, null ignored 760 * @param output the <code>OutputStream</code> to write to 761 * @param encoding the encoding to use, null means platform default 762 * @throws NullPointerException if output is null 763 * @throws IOException if an I/O error occurs 764 * @since Commons IO 2.0 765 */ 766 public static void write(CharSequence data, OutputStream output, String encoding) 767 throws IOException { 768 if (data != null) { 769 write(data.toString(), output, encoding); 770 } 771 } 772 773 // write String 774 //----------------------------------------------------------------------- 775 /** 776 * Writes chars from a <code>String</code> to a <code>Writer</code>. 777 * 778 * @param data the <code>String</code> to write, null ignored 779 * @param output the <code>Writer</code> to write to 780 * @throws NullPointerException if output is null 781 * @throws IOException if an I/O error occurs 782 * @since Commons IO 1.1 783 */ 784 public static void write(String data, Writer output) throws IOException { 785 if (data != null) { 786 output.write(data); 787 } 788 } 789 790 /** 791 * Writes chars from a <code>String</code> to bytes on an 792 * <code>OutputStream</code> using the default character encoding of the 793 * platform. 794 * <p> 795 * This method uses {@link String#getBytes()}. 796 * 797 * @param data the <code>String</code> to write, null ignored 798 * @param output the <code>OutputStream</code> to write to 799 * @throws NullPointerException if output is null 800 * @throws IOException if an I/O error occurs 801 * @since Commons IO 1.1 802 */ 803 public static void write(String data, OutputStream output) 804 throws IOException { 805 if (data != null) { 806 output.write(data.getBytes()); 807 } 808 } 809 810 /** 811 * Writes chars from a <code>String</code> to bytes on an 812 * <code>OutputStream</code> using the specified character encoding. 813 * <p> 814 * Character encoding names can be found at 815 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 816 * <p> 817 * This method uses {@link String#getBytes(String)}. 818 * 819 * @param data the <code>String</code> to write, null ignored 820 * @param output the <code>OutputStream</code> to write to 821 * @param encoding the encoding to use, null means platform default 822 * @throws NullPointerException if output is null 823 * @throws IOException if an I/O error occurs 824 * @since Commons IO 1.1 825 */ 826 public static void write(String data, OutputStream output, String encoding) 827 throws IOException { 828 if (data != null) { 829 if (encoding == null) { 830 write(data, output); 831 } else { 832 output.write(data.getBytes(encoding)); 833 } 834 } 835 } 836 837 // write StringBuffer 838 //----------------------------------------------------------------------- 839 /** 840 * Writes chars from a <code>StringBuffer</code> to a <code>Writer</code>. 841 * 842 * @param data the <code>StringBuffer</code> to write, null ignored 843 * @param output the <code>Writer</code> to write to 844 * @throws NullPointerException if output is null 845 * @throws IOException if an I/O error occurs 846 * @since Commons IO 1.1 847 * @deprecated replaced by write(CharSequence, Writer) 848 */ 849 @Deprecated 850 public static void write(StringBuffer data, Writer output) 851 throws IOException { 852 if (data != null) { 853 output.write(data.toString()); 854 } 855 } 856 857 /** 858 * Writes chars from a <code>StringBuffer</code> to bytes on an 859 * <code>OutputStream</code> using the default character encoding of the 860 * platform. 861 * <p> 862 * This method uses {@link String#getBytes()}. 863 * 864 * @param data the <code>StringBuffer</code> to write, null ignored 865 * @param output the <code>OutputStream</code> to write to 866 * @throws NullPointerException if output is null 867 * @throws IOException if an I/O error occurs 868 * @since Commons IO 1.1 869 * @deprecated replaced by write(CharSequence, OutputStream) 870 */ 871 @Deprecated 872 public static void write(StringBuffer data, OutputStream output) 873 throws IOException { 874 if (data != null) { 875 output.write(data.toString().getBytes()); 876 } 877 } 878 879 /** 880 * Writes chars from a <code>StringBuffer</code> to bytes on an 881 * <code>OutputStream</code> using the specified character encoding. 882 * <p> 883 * Character encoding names can be found at 884 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 885 * <p> 886 * This method uses {@link String#getBytes(String)}. 887 * 888 * @param data the <code>StringBuffer</code> to write, null ignored 889 * @param output the <code>OutputStream</code> to write to 890 * @param encoding the encoding to use, null means platform default 891 * @throws NullPointerException if output is null 892 * @throws IOException if an I/O error occurs 893 * @since Commons IO 1.1 894 * @deprecated replaced by write(CharSequence, OutputStream, String) 895 */ 896 @Deprecated 897 public static void write(StringBuffer data, OutputStream output, 898 String encoding) throws IOException { 899 if (data != null) { 900 if (encoding == null) { 901 write(data, output); 902 } else { 903 output.write(data.toString().getBytes(encoding)); 904 } 905 } 906 } 907 908 // copy from InputStream 909 //----------------------------------------------------------------------- 910 /** 911 * Copy bytes from an <code>InputStream</code> to an 912 * <code>OutputStream</code>. 913 * <p> 914 * This method buffers the input internally, so there is no need to use a 915 * <code>BufferedInputStream</code>. 916 * <p> 917 * Large streams (over 2GB) will return a bytes copied value of 918 * <code>-1</code> after the copy has completed since the correct 919 * number of bytes cannot be returned as an int. For large streams 920 * use the <code>copyLarge(InputStream, OutputStream)</code> method. 921 * 922 * @param input the <code>InputStream</code> to read from 923 * @param output the <code>OutputStream</code> to write to 924 * @return the number of bytes copied 925 * @throws NullPointerException if the input or output is null 926 * @throws IOException if an I/O error occurs 927 * @throws ArithmeticException if the byte count is too large 928 * @since Commons IO 1.1 929 */ 930 public static int copy(InputStream input, OutputStream output) throws IOException { 931 long count = copyLarge(input, output); 932 if (count > Integer.MAX_VALUE) { 933 return -1; 934 } 935 return (int) count; 936 } 937 938 /** 939 * Copy bytes from a large (over 2GB) <code>InputStream</code> to an 940 * <code>OutputStream</code>. 941 * <p> 942 * This method buffers the input internally, so there is no need to use a 943 * <code>BufferedInputStream</code>. 944 * 945 * @param input the <code>InputStream</code> to read from 946 * @param output the <code>OutputStream</code> to write to 947 * @return the number of bytes copied 948 * @throws NullPointerException if the input or output is null 949 * @throws IOException if an I/O error occurs 950 * @since Commons IO 1.3 951 */ 952 public static long copyLarge(InputStream input, OutputStream output) 953 throws IOException { 954 byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; 955 long count = 0; 956 int n = 0; 957 while (-1 != (n = input.read(buffer))) { 958 output.write(buffer, 0, n); 959 count += n; 960 } 961 return count; 962 } 963 964 /** 965 * Copy bytes from an <code>InputStream</code> to chars on a 966 * <code>Writer</code> using the default character encoding of the platform. 967 * <p> 968 * This method buffers the input internally, so there is no need to use a 969 * <code>BufferedInputStream</code>. 970 * <p> 971 * This method uses {@link InputStreamReader}. 972 * 973 * @param input the <code>InputStream</code> to read from 974 * @param output the <code>Writer</code> to write to 975 * @throws NullPointerException if the input or output is null 976 * @throws IOException if an I/O error occurs 977 * @since Commons IO 1.1 978 */ 979 public static void copy(InputStream input, Writer output) 980 throws IOException { 981 InputStreamReader in = new InputStreamReader(input); 982 copy(in, output); 983 } 984 985 /** 986 * Copy bytes from an <code>InputStream</code> to chars on a 987 * <code>Writer</code> using the specified character encoding. 988 * <p> 989 * This method buffers the input internally, so there is no need to use a 990 * <code>BufferedInputStream</code>. 991 * <p> 992 * Character encoding names can be found at 993 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 994 * <p> 995 * This method uses {@link InputStreamReader}. 996 * 997 * @param input the <code>InputStream</code> to read from 998 * @param output the <code>Writer</code> to write to 999 * @param encoding the encoding to use, null means platform default 1000 * @throws NullPointerException if the input or output is null 1001 * @throws IOException if an I/O error occurs 1002 * @since Commons IO 1.1 1003 */ 1004 public static void copy(InputStream input, Writer output, String encoding) 1005 throws IOException { 1006 if (encoding == null) { 1007 copy(input, output); 1008 } else { 1009 InputStreamReader in = new InputStreamReader(input, encoding); 1010 copy(in, output); 1011 } 1012 } 1013 1014 // copy from Reader 1015 //----------------------------------------------------------------------- 1016 /** 1017 * Copy chars from a <code>Reader</code> to a <code>Writer</code>. 1018 * <p> 1019 * This method buffers the input internally, so there is no need to use a 1020 * <code>BufferedReader</code>. 1021 * <p> 1022 * Large streams (over 2GB) will return a chars copied value of 1023 * <code>-1</code> after the copy has completed since the correct 1024 * number of chars cannot be returned as an int. For large streams 1025 * use the <code>copyLarge(Reader, Writer)</code> method. 1026 * 1027 * @param input the <code>Reader</code> to read from 1028 * @param output the <code>Writer</code> to write to 1029 * @return the number of characters copied 1030 * @throws NullPointerException if the input or output is null 1031 * @throws IOException if an I/O error occurs 1032 * @throws ArithmeticException if the character count is too large 1033 * @since Commons IO 1.1 1034 */ 1035 public static int copy(Reader input, Writer output) throws IOException { 1036 long count = copyLarge(input, output); 1037 if (count > Integer.MAX_VALUE) { 1038 return -1; 1039 } 1040 return (int) count; 1041 } 1042 1043 /** 1044 * Copy chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>. 1045 * <p> 1046 * This method buffers the input internally, so there is no need to use a 1047 * <code>BufferedReader</code>. 1048 * 1049 * @param input the <code>Reader</code> to read from 1050 * @param output the <code>Writer</code> to write to 1051 * @return the number of characters copied 1052 * @throws NullPointerException if the input or output is null 1053 * @throws IOException if an I/O error occurs 1054 * @since Commons IO 1.3 1055 */ 1056 public static long copyLarge(Reader input, Writer output) throws IOException { 1057 char[] buffer = new char[DEFAULT_BUFFER_SIZE]; 1058 long count = 0; 1059 int n = 0; 1060 while (-1 != (n = input.read(buffer))) { 1061 output.write(buffer, 0, n); 1062 count += n; 1063 } 1064 return count; 1065 } 1066 1067 /** 1068 * Copy chars from a <code>Reader</code> to bytes on an 1069 * <code>OutputStream</code> using the default character encoding of the 1070 * platform, and calling flush. 1071 * <p> 1072 * This method buffers the input internally, so there is no need to use a 1073 * <code>BufferedReader</code>. 1074 * <p> 1075 * Due to the implementation of OutputStreamWriter, this method performs a 1076 * flush. 1077 * <p> 1078 * This method uses {@link OutputStreamWriter}. 1079 * 1080 * @param input the <code>Reader</code> to read from 1081 * @param output the <code>OutputStream</code> to write to 1082 * @throws NullPointerException if the input or output is null 1083 * @throws IOException if an I/O error occurs 1084 * @since Commons IO 1.1 1085 */ 1086 public static void copy(Reader input, OutputStream output) 1087 throws IOException { 1088 OutputStreamWriter out = new OutputStreamWriter(output); 1089 copy(input, out); 1090 // XXX Unless anyone is planning on rewriting OutputStreamWriter, we 1091 // have to flush here. 1092 out.flush(); 1093 } 1094 1095 /** 1096 * Copy chars from a <code>Reader</code> to bytes on an 1097 * <code>OutputStream</code> using the specified character encoding, and 1098 * calling flush. 1099 * <p> 1100 * This method buffers the input internally, so there is no need to use a 1101 * <code>BufferedReader</code>. 1102 * <p> 1103 * Character encoding names can be found at 1104 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 1105 * <p> 1106 * Due to the implementation of OutputStreamWriter, this method performs a 1107 * flush. 1108 * <p> 1109 * This method uses {@link OutputStreamWriter}. 1110 * 1111 * @param input the <code>Reader</code> to read from 1112 * @param output the <code>OutputStream</code> to write to 1113 * @param encoding the encoding to use, null means platform default 1114 * @throws NullPointerException if the input or output is null 1115 * @throws IOException if an I/O error occurs 1116 * @since Commons IO 1.1 1117 */ 1118 public static void copy(Reader input, OutputStream output, String encoding) 1119 throws IOException { 1120 if (encoding == null) { 1121 copy(input, output); 1122 } else { 1123 OutputStreamWriter out = new OutputStreamWriter(output, encoding); 1124 copy(input, out); 1125 // XXX Unless anyone is planning on rewriting OutputStreamWriter, 1126 // we have to flush here. 1127 out.flush(); 1128 } 1129 } 1130 1131 // content equals 1132 //----------------------------------------------------------------------- 1133 /** 1134 * Compare the contents of two Streams to determine if they are equal or 1135 * not. 1136 * <p> 1137 * This method buffers the input internally using 1138 * <code>BufferedInputStream</code> if they are not already buffered. 1139 * 1140 * @param input1 the first stream 1141 * @param input2 the second stream 1142 * @return true if the content of the streams are equal or they both don't 1143 * exist, false otherwise 1144 * @throws NullPointerException if either input is null 1145 * @throws IOException if an I/O error occurs 1146 */ 1147 public static boolean contentEquals(InputStream input1, InputStream input2) 1148 throws IOException { 1149 if (!(input1 instanceof BufferedInputStream)) { 1150 input1 = new BufferedInputStream(input1); 1151 } 1152 if (!(input2 instanceof BufferedInputStream)) { 1153 input2 = new BufferedInputStream(input2); 1154 } 1155 1156 int ch = input1.read(); 1157 while (-1 != ch) { 1158 int ch2 = input2.read(); 1159 if (ch != ch2) { 1160 return false; 1161 } 1162 ch = input1.read(); 1163 } 1164 1165 int ch2 = input2.read(); 1166 return (ch2 == -1); 1167 } 1168 1169 /** 1170 * Compare the contents of two Readers to determine if they are equal or 1171 * not. 1172 * <p> 1173 * This method buffers the input internally using 1174 * <code>BufferedReader</code> if they are not already buffered. 1175 * 1176 * @param input1 the first reader 1177 * @param input2 the second reader 1178 * @return true if the content of the readers are equal or they both don't 1179 * exist, false otherwise 1180 * @throws NullPointerException if either input is null 1181 * @throws IOException if an I/O error occurs 1182 * @since Commons IO 1.1 1183 */ 1184 public static boolean contentEquals(Reader input1, Reader input2) 1185 throws IOException { 1186 if (!(input1 instanceof BufferedReader)) { 1187 input1 = new BufferedReader(input1); 1188 } 1189 if (!(input2 instanceof BufferedReader)) { 1190 input2 = new BufferedReader(input2); 1191 } 1192 1193 int ch = input1.read(); 1194 while (-1 != ch) { 1195 int ch2 = input2.read(); 1196 if (ch != ch2) { 1197 return false; 1198 } 1199 ch = input1.read(); 1200 } 1201 1202 int ch2 = input2.read(); 1203 return (ch2 == -1); 1204 } 1205 1206 }