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