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); out.println()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 */ IOUtils()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 */ closeQuietly(Reader input)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 */ closeQuietly(Writer output)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 */ closeQuietly(InputStream input)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 */ closeQuietly(OutputStream output)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 */ toByteArray(InputStream input)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 */ toByteArray(Reader input)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 */ toByteArray(Reader input, String encoding)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 @Deprecated toByteArray(String input)277 public static byte[] toByteArray(String input) throws IOException { 278 return input.getBytes(); 279 } 280 281 // read char[] 282 //----------------------------------------------------------------------- 283 /** 284 * Get the contents of an <code>InputStream</code> as a character array 285 * using the default character encoding of the platform. 286 * <p> 287 * This method buffers the input internally, so there is no need to use a 288 * <code>BufferedInputStream</code>. 289 * 290 * @param is the <code>InputStream</code> to read from 291 * @return the requested character array 292 * @throws NullPointerException if the input is null 293 * @throws IOException if an I/O error occurs 294 * @since Commons IO 1.1 295 */ toCharArray(InputStream is)296 public static char[] toCharArray(InputStream is) throws IOException { 297 CharArrayWriter output = new CharArrayWriter(); 298 copy(is, output); 299 return output.toCharArray(); 300 } 301 302 /** 303 * Get the contents of an <code>InputStream</code> as a character array 304 * using the specified character encoding. 305 * <p> 306 * Character encoding names can be found at 307 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 308 * <p> 309 * This method buffers the input internally, so there is no need to use a 310 * <code>BufferedInputStream</code>. 311 * 312 * @param is the <code>InputStream</code> to read from 313 * @param encoding the encoding to use, null means platform default 314 * @return the requested character array 315 * @throws NullPointerException if the input is null 316 * @throws IOException if an I/O error occurs 317 * @since Commons IO 1.1 318 */ toCharArray(InputStream is, String encoding)319 public static char[] toCharArray(InputStream is, String encoding) 320 throws IOException { 321 CharArrayWriter output = new CharArrayWriter(); 322 copy(is, output, encoding); 323 return output.toCharArray(); 324 } 325 326 /** 327 * Get the contents of a <code>Reader</code> as a character array. 328 * <p> 329 * This method buffers the input internally, so there is no need to use a 330 * <code>BufferedReader</code>. 331 * 332 * @param input the <code>Reader</code> to read from 333 * @return the requested character array 334 * @throws NullPointerException if the input is null 335 * @throws IOException if an I/O error occurs 336 * @since Commons IO 1.1 337 */ toCharArray(Reader input)338 public static char[] toCharArray(Reader input) throws IOException { 339 CharArrayWriter sw = new CharArrayWriter(); 340 copy(input, sw); 341 return sw.toCharArray(); 342 } 343 344 // read toString 345 //----------------------------------------------------------------------- 346 /** 347 * Get the contents of an <code>InputStream</code> as a String 348 * using the default character encoding of the platform. 349 * <p> 350 * This method buffers the input internally, so there is no need to use a 351 * <code>BufferedInputStream</code>. 352 * 353 * @param input the <code>InputStream</code> to read from 354 * @return the requested String 355 * @throws NullPointerException if the input is null 356 * @throws IOException if an I/O error occurs 357 */ toString(InputStream input)358 public static String toString(InputStream input) throws IOException { 359 StringWriter sw = new StringWriter(); 360 copy(input, sw); 361 return sw.toString(); 362 } 363 364 /** 365 * Get the contents of an <code>InputStream</code> as a String 366 * using the specified character encoding. 367 * <p> 368 * Character encoding names can be found at 369 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 370 * <p> 371 * This method buffers the input internally, so there is no need to use a 372 * <code>BufferedInputStream</code>. 373 * 374 * @param input the <code>InputStream</code> to read from 375 * @param encoding the encoding to use, null means platform default 376 * @return the requested String 377 * @throws NullPointerException if the input is null 378 * @throws IOException if an I/O error occurs 379 */ toString(InputStream input, String encoding)380 public static String toString(InputStream input, String encoding) 381 throws IOException { 382 StringWriter sw = new StringWriter(); 383 copy(input, sw, encoding); 384 return sw.toString(); 385 } 386 387 /** 388 * Get the contents of a <code>Reader</code> as a String. 389 * <p> 390 * This method buffers the input internally, so there is no need to use a 391 * <code>BufferedReader</code>. 392 * 393 * @param input the <code>Reader</code> to read from 394 * @return the requested String 395 * @throws NullPointerException if the input is null 396 * @throws IOException if an I/O error occurs 397 */ toString(Reader input)398 public static String toString(Reader input) throws IOException { 399 StringWriter sw = new StringWriter(); 400 copy(input, sw); 401 return sw.toString(); 402 } 403 404 /** 405 * Get the contents of a <code>byte[]</code> as a String 406 * using the default character encoding of the platform. 407 * 408 * @param input the byte array to read from 409 * @return the requested String 410 * @throws NullPointerException if the input is null 411 * @throws IOException if an I/O error occurs (never occurs) 412 * @deprecated Use {@link String#String(byte[])} 413 */ 414 @Deprecated toString(byte[] input)415 public static String toString(byte[] input) throws IOException { 416 return new String(input); 417 } 418 419 /** 420 * Get the contents of a <code>byte[]</code> as a String 421 * using the specified character encoding. 422 * <p> 423 * Character encoding names can be found at 424 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 425 * 426 * @param input the byte array to read from 427 * @param encoding the encoding to use, null means platform default 428 * @return the requested String 429 * @throws NullPointerException if the input is null 430 * @throws IOException if an I/O error occurs (never occurs) 431 * @deprecated Use {@link String#String(byte[],String)} 432 */ 433 @Deprecated toString(byte[] input, String encoding)434 public static String toString(byte[] input, String encoding) 435 throws IOException { 436 if (encoding == null) { 437 return new String(input); 438 } else { 439 return new String(input, encoding); 440 } 441 } 442 443 // readLines 444 //----------------------------------------------------------------------- 445 /** 446 * Get the contents of an <code>InputStream</code> as a list of Strings, 447 * one entry per line, using the default character encoding of the platform. 448 * <p> 449 * This method buffers the input internally, so there is no need to use a 450 * <code>BufferedInputStream</code>. 451 * 452 * @param input the <code>InputStream</code> to read from, not null 453 * @return the list of Strings, never null 454 * @throws NullPointerException if the input is null 455 * @throws IOException if an I/O error occurs 456 * @since Commons IO 1.1 457 */ readLines(InputStream input)458 public static List<String> readLines(InputStream input) throws IOException { 459 InputStreamReader reader = new InputStreamReader(input); 460 return readLines(reader); 461 } 462 463 /** 464 * Get the contents of an <code>InputStream</code> as a list of Strings, 465 * one entry per line, using the specified character encoding. 466 * <p> 467 * Character encoding names can be found at 468 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 469 * <p> 470 * This method buffers the input internally, so there is no need to use a 471 * <code>BufferedInputStream</code>. 472 * 473 * @param input the <code>InputStream</code> to read from, not null 474 * @param encoding the encoding to use, null means platform default 475 * @return the list of Strings, never null 476 * @throws NullPointerException if the input is null 477 * @throws IOException if an I/O error occurs 478 * @since Commons IO 1.1 479 */ readLines(InputStream input, String encoding)480 public static List<String> readLines(InputStream input, String encoding) throws IOException { 481 if (encoding == null) { 482 return readLines(input); 483 } else { 484 InputStreamReader reader = new InputStreamReader(input, encoding); 485 return readLines(reader); 486 } 487 } 488 489 /** 490 * Get the contents of a <code>Reader</code> as a list of Strings, 491 * one entry per line. 492 * <p> 493 * This method buffers the input internally, so there is no need to use a 494 * <code>BufferedReader</code>. 495 * 496 * @param input the <code>Reader</code> to read from, not null 497 * @return the list of Strings, never null 498 * @throws NullPointerException if the input is null 499 * @throws IOException if an I/O error occurs 500 * @since Commons IO 1.1 501 */ readLines(Reader input)502 public static List<String> readLines(Reader input) throws IOException { 503 BufferedReader reader = new BufferedReader(input); 504 List<String> list = new ArrayList<String>(); 505 String line = reader.readLine(); 506 while (line != null) { 507 list.add(line); 508 line = reader.readLine(); 509 } 510 return list; 511 } 512 513 // lineIterator 514 //----------------------------------------------------------------------- 515 /** 516 * Return an Iterator for the lines in a <code>Reader</code>. 517 * <p> 518 * <code>LineIterator</code> holds a reference to the open 519 * <code>Reader</code> specified here. When you have finished with the 520 * iterator you should close the reader to free internal resources. 521 * This can be done by closing the reader directly, or by calling 522 * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}. 523 * <p> 524 * The recommended usage pattern is: 525 * <pre> 526 * try { 527 * LineIterator it = IOUtils.lineIterator(reader); 528 * while (it.hasNext()) { 529 * String line = it.nextLine(); 530 * /// do something with line 531 * } 532 * } finally { 533 * IOUtils.closeQuietly(reader); 534 * } 535 * </pre> 536 * 537 * @param reader the <code>Reader</code> to read from, not null 538 * @return an Iterator of the lines in the reader, never null 539 * @throws IllegalArgumentException if the reader is null 540 * @since Commons IO 1.2 541 */ lineIterator(Reader reader)542 public static LineIterator lineIterator(Reader reader) { 543 return new LineIterator(reader); 544 } 545 546 /** 547 * Return an Iterator for the lines in an <code>InputStream</code>, using 548 * the character encoding specified (or default encoding if null). 549 * <p> 550 * <code>LineIterator</code> holds a reference to the open 551 * <code>InputStream</code> specified here. When you have finished with 552 * the iterator you should close the stream to free internal resources. 553 * This can be done by closing the stream directly, or by calling 554 * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}. 555 * <p> 556 * The recommended usage pattern is: 557 * <pre> 558 * try { 559 * LineIterator it = IOUtils.lineIterator(stream, "UTF-8"); 560 * while (it.hasNext()) { 561 * String line = it.nextLine(); 562 * /// do something with line 563 * } 564 * } finally { 565 * IOUtils.closeQuietly(stream); 566 * } 567 * </pre> 568 * 569 * @param input the <code>InputStream</code> to read from, not null 570 * @param encoding the encoding to use, null means platform default 571 * @return an Iterator of the lines in the reader, never null 572 * @throws IllegalArgumentException if the input is null 573 * @throws IOException if an I/O error occurs, such as if the encoding is invalid 574 * @since Commons IO 1.2 575 */ lineIterator(InputStream input, String encoding)576 public static LineIterator lineIterator(InputStream input, String encoding) 577 throws IOException { 578 Reader reader = null; 579 if (encoding == null) { 580 reader = new InputStreamReader(input); 581 } else { 582 reader = new InputStreamReader(input, encoding); 583 } 584 return new LineIterator(reader); 585 } 586 587 //----------------------------------------------------------------------- 588 /** 589 * Convert the specified string to an input stream, encoded as bytes 590 * using the default character encoding of the platform. 591 * 592 * @param input the string to convert 593 * @return an input stream 594 * @since Commons IO 1.1 595 */ toInputStream(String input)596 public static InputStream toInputStream(String input) { 597 byte[] bytes = input.getBytes(); 598 return new ByteArrayInputStream(bytes); 599 } 600 601 /** 602 * Convert the specified string to an input stream, encoded as bytes 603 * using the specified character encoding. 604 * <p> 605 * Character encoding names can be found at 606 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 607 * 608 * @param input the string to convert 609 * @param encoding the encoding to use, null means platform default 610 * @throws IOException if the encoding is invalid 611 * @return an input stream 612 * @since Commons IO 1.1 613 */ toInputStream(String input, String encoding)614 public static InputStream toInputStream(String input, String encoding) throws IOException { 615 byte[] bytes = encoding != null ? input.getBytes(encoding) : input.getBytes(); 616 return new ByteArrayInputStream(bytes); 617 } 618 619 // write byte[] 620 //----------------------------------------------------------------------- 621 /** 622 * Writes bytes from a <code>byte[]</code> to an <code>OutputStream</code>. 623 * 624 * @param data the byte array to write, do not modify during output, 625 * null ignored 626 * @param output the <code>OutputStream</code> to write to 627 * @throws NullPointerException if output is null 628 * @throws IOException if an I/O error occurs 629 * @since Commons IO 1.1 630 */ write(byte[] data, OutputStream output)631 public static void write(byte[] data, OutputStream output) 632 throws IOException { 633 if (data != null) { 634 output.write(data); 635 } 636 } 637 638 /** 639 * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code> 640 * using the default character encoding of the platform. 641 * <p> 642 * This method uses {@link String#String(byte[])}. 643 * 644 * @param data the byte array to write, do not modify during output, 645 * null ignored 646 * @param output the <code>Writer</code> to write to 647 * @throws NullPointerException if output is null 648 * @throws IOException if an I/O error occurs 649 * @since Commons IO 1.1 650 */ write(byte[] data, Writer output)651 public static void write(byte[] data, Writer output) throws IOException { 652 if (data != null) { 653 output.write(new String(data)); 654 } 655 } 656 657 /** 658 * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code> 659 * using the specified character encoding. 660 * <p> 661 * Character encoding names can be found at 662 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 663 * <p> 664 * This method uses {@link String#String(byte[], String)}. 665 * 666 * @param data the byte array to write, do not modify during output, 667 * null ignored 668 * @param output the <code>Writer</code> to write to 669 * @param encoding the encoding to use, null means platform default 670 * @throws NullPointerException if output is null 671 * @throws IOException if an I/O error occurs 672 * @since Commons IO 1.1 673 */ write(byte[] data, Writer output, String encoding)674 public static void write(byte[] data, Writer output, String encoding) 675 throws IOException { 676 if (data != null) { 677 if (encoding == null) { 678 write(data, output); 679 } else { 680 output.write(new String(data, encoding)); 681 } 682 } 683 } 684 685 // write char[] 686 //----------------------------------------------------------------------- 687 /** 688 * Writes chars from a <code>char[]</code> to a <code>Writer</code> 689 * using the default character encoding of the platform. 690 * 691 * @param data the char array to write, do not modify during output, 692 * null ignored 693 * @param output the <code>Writer</code> to write to 694 * @throws NullPointerException if output is null 695 * @throws IOException if an I/O error occurs 696 * @since Commons IO 1.1 697 */ write(char[] data, Writer output)698 public static void write(char[] data, Writer output) throws IOException { 699 if (data != null) { 700 output.write(data); 701 } 702 } 703 704 /** 705 * Writes chars from a <code>char[]</code> to bytes on an 706 * <code>OutputStream</code>. 707 * <p> 708 * This method uses {@link String#String(char[])} and 709 * {@link String#getBytes()}. 710 * 711 * @param data the char array to write, do not modify during output, 712 * null ignored 713 * @param output the <code>OutputStream</code> to write to 714 * @throws NullPointerException if output is null 715 * @throws IOException if an I/O error occurs 716 * @since Commons IO 1.1 717 */ write(char[] data, OutputStream output)718 public static void write(char[] data, OutputStream output) 719 throws IOException { 720 if (data != null) { 721 output.write(new String(data).getBytes()); 722 } 723 } 724 725 /** 726 * Writes chars from a <code>char[]</code> to bytes on an 727 * <code>OutputStream</code> using the specified character encoding. 728 * <p> 729 * Character encoding names can be found at 730 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 731 * <p> 732 * This method uses {@link String#String(char[])} and 733 * {@link String#getBytes(String)}. 734 * 735 * @param data the char array to write, do not modify during output, 736 * null ignored 737 * @param output the <code>OutputStream</code> to write to 738 * @param encoding the encoding to use, null means platform default 739 * @throws NullPointerException if output is null 740 * @throws IOException if an I/O error occurs 741 * @since Commons IO 1.1 742 */ write(char[] data, OutputStream output, String encoding)743 public static void write(char[] data, OutputStream output, String encoding) 744 throws IOException { 745 if (data != null) { 746 if (encoding == null) { 747 write(data, output); 748 } else { 749 output.write(new String(data).getBytes(encoding)); 750 } 751 } 752 } 753 754 // write String 755 //----------------------------------------------------------------------- 756 /** 757 * Writes chars from a <code>String</code> to a <code>Writer</code>. 758 * 759 * @param data the <code>String</code> to write, null ignored 760 * @param output the <code>Writer</code> to write to 761 * @throws NullPointerException if output is null 762 * @throws IOException if an I/O error occurs 763 * @since Commons IO 1.1 764 */ write(String data, Writer output)765 public static void write(String data, Writer output) throws IOException { 766 if (data != null) { 767 output.write(data); 768 } 769 } 770 771 /** 772 * Writes chars from a <code>String</code> to bytes on an 773 * <code>OutputStream</code> using the default character encoding of the 774 * platform. 775 * <p> 776 * This method uses {@link String#getBytes()}. 777 * 778 * @param data the <code>String</code> to write, null ignored 779 * @param output the <code>OutputStream</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 */ write(String data, OutputStream output)784 public static void write(String data, OutputStream output) 785 throws IOException { 786 if (data != null) { 787 output.write(data.getBytes()); 788 } 789 } 790 791 /** 792 * Writes chars from a <code>String</code> to bytes on an 793 * <code>OutputStream</code> using the specified character encoding. 794 * <p> 795 * Character encoding names can be found at 796 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 797 * <p> 798 * This method uses {@link String#getBytes(String)}. 799 * 800 * @param data the <code>String</code> to write, null ignored 801 * @param output the <code>OutputStream</code> to write to 802 * @param encoding the encoding to use, null means platform default 803 * @throws NullPointerException if output is null 804 * @throws IOException if an I/O error occurs 805 * @since Commons IO 1.1 806 */ write(String data, OutputStream output, String encoding)807 public static void write(String data, OutputStream output, String encoding) 808 throws IOException { 809 if (data != null) { 810 if (encoding == null) { 811 write(data, output); 812 } else { 813 output.write(data.getBytes(encoding)); 814 } 815 } 816 } 817 818 // write StringBuffer 819 //----------------------------------------------------------------------- 820 /** 821 * Writes chars from a <code>StringBuffer</code> to a <code>Writer</code>. 822 * 823 * @param data the <code>StringBuffer</code> to write, null ignored 824 * @param output the <code>Writer</code> to write to 825 * @throws NullPointerException if output is null 826 * @throws IOException if an I/O error occurs 827 * @since Commons IO 1.1 828 */ write(StringBuffer data, Writer output)829 public static void write(StringBuffer data, Writer output) 830 throws IOException { 831 if (data != null) { 832 output.write(data.toString()); 833 } 834 } 835 836 /** 837 * Writes chars from a <code>StringBuffer</code> to bytes on an 838 * <code>OutputStream</code> using the default character encoding of the 839 * platform. 840 * <p> 841 * This method uses {@link String#getBytes()}. 842 * 843 * @param data the <code>StringBuffer</code> to write, null ignored 844 * @param output the <code>OutputStream</code> to write to 845 * @throws NullPointerException if output is null 846 * @throws IOException if an I/O error occurs 847 * @since Commons IO 1.1 848 */ write(StringBuffer data, OutputStream output)849 public static void write(StringBuffer data, OutputStream output) 850 throws IOException { 851 if (data != null) { 852 output.write(data.toString().getBytes()); 853 } 854 } 855 856 /** 857 * Writes chars from a <code>StringBuffer</code> to bytes on an 858 * <code>OutputStream</code> using the specified character encoding. 859 * <p> 860 * Character encoding names can be found at 861 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 862 * <p> 863 * This method uses {@link String#getBytes(String)}. 864 * 865 * @param data the <code>StringBuffer</code> to write, null ignored 866 * @param output the <code>OutputStream</code> to write to 867 * @param encoding the encoding to use, null means platform default 868 * @throws NullPointerException if output is null 869 * @throws IOException if an I/O error occurs 870 * @since Commons IO 1.1 871 */ write(StringBuffer data, OutputStream output, String encoding)872 public static void write(StringBuffer data, OutputStream output, 873 String encoding) throws IOException { 874 if (data != null) { 875 if (encoding == null) { 876 write(data, output); 877 } else { 878 output.write(data.toString().getBytes(encoding)); 879 } 880 } 881 } 882 883 // writeLines 884 //----------------------------------------------------------------------- 885 /** 886 * Writes the <code>toString()</code> value of each item in a collection to 887 * an <code>OutputStream</code> line by line, using the default character 888 * encoding of the platform and the specified line ending. 889 * 890 * @param lines the lines to write, null entries produce blank lines 891 * @param lineEnding the line separator to use, null is system default 892 * @param output the <code>OutputStream</code> to write to, not null, not closed 893 * @throws NullPointerException if the output is null 894 * @throws IOException if an I/O error occurs 895 * @since Commons IO 1.1 896 */ writeLines(Collection<Object> lines, String lineEnding, OutputStream output)897 public static void writeLines(Collection<Object> lines, String lineEnding, 898 OutputStream output) throws IOException { 899 if (lines == null) { 900 return; 901 } 902 if (lineEnding == null) { 903 lineEnding = LINE_SEPARATOR; 904 } 905 for (Iterator<Object> it = lines.iterator(); it.hasNext(); ) { 906 Object line = it.next(); 907 if (line != null) { 908 output.write(line.toString().getBytes()); 909 } 910 output.write(lineEnding.getBytes()); 911 } 912 } 913 914 /** 915 * Writes the <code>toString()</code> value of each item in a collection to 916 * an <code>OutputStream</code> line by line, using the specified character 917 * encoding and the specified line ending. 918 * <p> 919 * Character encoding names can be found at 920 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 921 * 922 * @param lines the lines to write, null entries produce blank lines 923 * @param lineEnding the line separator to use, null is system default 924 * @param output the <code>OutputStream</code> to write to, not null, not closed 925 * @param encoding the encoding to use, null means platform default 926 * @throws NullPointerException if the output is null 927 * @throws IOException if an I/O error occurs 928 * @since Commons IO 1.1 929 */ writeLines(Collection<Object> lines, String lineEnding, OutputStream output, String encoding)930 public static void writeLines(Collection<Object> lines, String lineEnding, 931 OutputStream output, String encoding) throws IOException { 932 if (encoding == null) { 933 writeLines(lines, lineEnding, output); 934 } else { 935 if (lines == null) { 936 return; 937 } 938 if (lineEnding == null) { 939 lineEnding = LINE_SEPARATOR; 940 } 941 for (Iterator<Object> it = lines.iterator(); it.hasNext(); ) { 942 Object line = it.next(); 943 if (line != null) { 944 output.write(line.toString().getBytes(encoding)); 945 } 946 output.write(lineEnding.getBytes(encoding)); 947 } 948 } 949 } 950 951 /** 952 * Writes the <code>toString()</code> value of each item in a collection to 953 * a <code>Writer</code> line by line, using the specified line ending. 954 * 955 * @param lines the lines to write, null entries produce blank lines 956 * @param lineEnding the line separator to use, null is system default 957 * @param writer the <code>Writer</code> to write to, not null, not closed 958 * @throws NullPointerException if the input is null 959 * @throws IOException if an I/O error occurs 960 * @since Commons IO 1.1 961 */ writeLines(Collection<Object> lines, String lineEnding, Writer writer)962 public static void writeLines(Collection<Object> lines, String lineEnding, 963 Writer writer) throws IOException { 964 if (lines == null) { 965 return; 966 } 967 if (lineEnding == null) { 968 lineEnding = LINE_SEPARATOR; 969 } 970 for (Iterator<Object> it = lines.iterator(); it.hasNext(); ) { 971 Object line = it.next(); 972 if (line != null) { 973 writer.write(line.toString()); 974 } 975 writer.write(lineEnding); 976 } 977 } 978 979 // copy from InputStream 980 //----------------------------------------------------------------------- 981 /** 982 * Copy bytes from an <code>InputStream</code> to an 983 * <code>OutputStream</code>. 984 * <p> 985 * This method buffers the input internally, so there is no need to use a 986 * <code>BufferedInputStream</code>. 987 * <p> 988 * Large streams (over 2GB) will return a bytes copied value of 989 * <code>-1</code> after the copy has completed since the correct 990 * number of bytes cannot be returned as an int. For large streams 991 * use the <code>copyLarge(InputStream, OutputStream)</code> method. 992 * 993 * @param input the <code>InputStream</code> to read from 994 * @param output the <code>OutputStream</code> to write to 995 * @return the number of bytes copied 996 * @throws NullPointerException if the input or output is null 997 * @throws IOException if an I/O error occurs 998 * @throws ArithmeticException if the byte count is too large 999 * @since Commons IO 1.1 1000 */ copy(InputStream input, OutputStream output)1001 public static int copy(InputStream input, OutputStream output) throws IOException { 1002 long count = copyLarge(input, output); 1003 if (count > Integer.MAX_VALUE) { 1004 return -1; 1005 } 1006 return (int) count; 1007 } 1008 1009 /** 1010 * Copy bytes from a large (over 2GB) <code>InputStream</code> to an 1011 * <code>OutputStream</code>. 1012 * <p> 1013 * This method buffers the input internally, so there is no need to use a 1014 * <code>BufferedInputStream</code>. 1015 * 1016 * @param input the <code>InputStream</code> to read from 1017 * @param output the <code>OutputStream</code> to write to 1018 * @return the number of bytes copied 1019 * @throws NullPointerException if the input or output is null 1020 * @throws IOException if an I/O error occurs 1021 * @since Commons IO 1.3 1022 */ copyLarge(InputStream input, OutputStream output)1023 public static long copyLarge(InputStream input, OutputStream output) 1024 throws IOException { 1025 byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; 1026 long count = 0; 1027 int n = 0; 1028 while (-1 != (n = input.read(buffer))) { 1029 output.write(buffer, 0, n); 1030 count += n; 1031 } 1032 return count; 1033 } 1034 1035 /** 1036 * Copy bytes from an <code>InputStream</code> to chars on a 1037 * <code>Writer</code> using the default character encoding of the platform. 1038 * <p> 1039 * This method buffers the input internally, so there is no need to use a 1040 * <code>BufferedInputStream</code>. 1041 * <p> 1042 * This method uses {@link InputStreamReader}. 1043 * 1044 * @param input the <code>InputStream</code> to read from 1045 * @param output the <code>Writer</code> to write to 1046 * @throws NullPointerException if the input or output is null 1047 * @throws IOException if an I/O error occurs 1048 * @since Commons IO 1.1 1049 */ copy(InputStream input, Writer output)1050 public static void copy(InputStream input, Writer output) 1051 throws IOException { 1052 InputStreamReader in = new InputStreamReader(input); 1053 copy(in, output); 1054 } 1055 1056 /** 1057 * Copy bytes from an <code>InputStream</code> to chars on a 1058 * <code>Writer</code> using the specified character encoding. 1059 * <p> 1060 * This method buffers the input internally, so there is no need to use a 1061 * <code>BufferedInputStream</code>. 1062 * <p> 1063 * Character encoding names can be found at 1064 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 1065 * <p> 1066 * This method uses {@link InputStreamReader}. 1067 * 1068 * @param input the <code>InputStream</code> to read from 1069 * @param output the <code>Writer</code> to write to 1070 * @param encoding the encoding to use, null means platform default 1071 * @throws NullPointerException if the input or output is null 1072 * @throws IOException if an I/O error occurs 1073 * @since Commons IO 1.1 1074 */ copy(InputStream input, Writer output, String encoding)1075 public static void copy(InputStream input, Writer output, String encoding) 1076 throws IOException { 1077 if (encoding == null) { 1078 copy(input, output); 1079 } else { 1080 InputStreamReader in = new InputStreamReader(input, encoding); 1081 copy(in, output); 1082 } 1083 } 1084 1085 // copy from Reader 1086 //----------------------------------------------------------------------- 1087 /** 1088 * Copy chars from a <code>Reader</code> to a <code>Writer</code>. 1089 * <p> 1090 * This method buffers the input internally, so there is no need to use a 1091 * <code>BufferedReader</code>. 1092 * <p> 1093 * Large streams (over 2GB) will return a chars copied value of 1094 * <code>-1</code> after the copy has completed since the correct 1095 * number of chars cannot be returned as an int. For large streams 1096 * use the <code>copyLarge(Reader, Writer)</code> method. 1097 * 1098 * @param input the <code>Reader</code> to read from 1099 * @param output the <code>Writer</code> to write to 1100 * @return the number of characters copied 1101 * @throws NullPointerException if the input or output is null 1102 * @throws IOException if an I/O error occurs 1103 * @throws ArithmeticException if the character count is too large 1104 * @since Commons IO 1.1 1105 */ copy(Reader input, Writer output)1106 public static int copy(Reader input, Writer output) throws IOException { 1107 long count = copyLarge(input, output); 1108 if (count > Integer.MAX_VALUE) { 1109 return -1; 1110 } 1111 return (int) count; 1112 } 1113 1114 /** 1115 * Copy chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>. 1116 * <p> 1117 * This method buffers the input internally, so there is no need to use a 1118 * <code>BufferedReader</code>. 1119 * 1120 * @param input the <code>Reader</code> to read from 1121 * @param output the <code>Writer</code> to write to 1122 * @return the number of characters copied 1123 * @throws NullPointerException if the input or output is null 1124 * @throws IOException if an I/O error occurs 1125 * @since Commons IO 1.3 1126 */ copyLarge(Reader input, Writer output)1127 public static long copyLarge(Reader input, Writer output) throws IOException { 1128 char[] buffer = new char[DEFAULT_BUFFER_SIZE]; 1129 long count = 0; 1130 int n = 0; 1131 while (-1 != (n = input.read(buffer))) { 1132 output.write(buffer, 0, n); 1133 count += n; 1134 } 1135 return count; 1136 } 1137 1138 /** 1139 * Copy chars from a <code>Reader</code> to bytes on an 1140 * <code>OutputStream</code> using the default character encoding of the 1141 * platform, and calling flush. 1142 * <p> 1143 * This method buffers the input internally, so there is no need to use a 1144 * <code>BufferedReader</code>. 1145 * <p> 1146 * Due to the implementation of OutputStreamWriter, this method performs a 1147 * flush. 1148 * <p> 1149 * This method uses {@link OutputStreamWriter}. 1150 * 1151 * @param input the <code>Reader</code> to read from 1152 * @param output the <code>OutputStream</code> to write to 1153 * @throws NullPointerException if the input or output is null 1154 * @throws IOException if an I/O error occurs 1155 * @since Commons IO 1.1 1156 */ copy(Reader input, OutputStream output)1157 public static void copy(Reader input, OutputStream output) 1158 throws IOException { 1159 OutputStreamWriter out = new OutputStreamWriter(output); 1160 copy(input, out); 1161 // XXX Unless anyone is planning on rewriting OutputStreamWriter, we 1162 // have to flush here. 1163 out.flush(); 1164 } 1165 1166 /** 1167 * Copy chars from a <code>Reader</code> to bytes on an 1168 * <code>OutputStream</code> using the specified character encoding, and 1169 * calling flush. 1170 * <p> 1171 * This method buffers the input internally, so there is no need to use a 1172 * <code>BufferedReader</code>. 1173 * <p> 1174 * Character encoding names can be found at 1175 * <a href="http://www.iana.org/assignments/character-sets">IANA</a>. 1176 * <p> 1177 * Due to the implementation of OutputStreamWriter, this method performs a 1178 * flush. 1179 * <p> 1180 * This method uses {@link OutputStreamWriter}. 1181 * 1182 * @param input the <code>Reader</code> to read from 1183 * @param output the <code>OutputStream</code> to write to 1184 * @param encoding the encoding to use, null means platform default 1185 * @throws NullPointerException if the input or output is null 1186 * @throws IOException if an I/O error occurs 1187 * @since Commons IO 1.1 1188 */ copy(Reader input, OutputStream output, String encoding)1189 public static void copy(Reader input, OutputStream output, String encoding) 1190 throws IOException { 1191 if (encoding == null) { 1192 copy(input, output); 1193 } else { 1194 OutputStreamWriter out = new OutputStreamWriter(output, encoding); 1195 copy(input, out); 1196 // XXX Unless anyone is planning on rewriting OutputStreamWriter, 1197 // we have to flush here. 1198 out.flush(); 1199 } 1200 } 1201 1202 // content equals 1203 //----------------------------------------------------------------------- 1204 /** 1205 * Compare the contents of two Streams to determine if they are equal or 1206 * not. 1207 * <p> 1208 * This method buffers the input internally using 1209 * <code>BufferedInputStream</code> if they are not already buffered. 1210 * 1211 * @param input1 the first stream 1212 * @param input2 the second stream 1213 * @return true if the content of the streams are equal or they both don't 1214 * exist, false otherwise 1215 * @throws NullPointerException if either input is null 1216 * @throws IOException if an I/O error occurs 1217 */ contentEquals(InputStream input1, InputStream input2)1218 public static boolean contentEquals(InputStream input1, InputStream input2) 1219 throws IOException { 1220 if (!(input1 instanceof BufferedInputStream)) { 1221 input1 = new BufferedInputStream(input1); 1222 } 1223 if (!(input2 instanceof BufferedInputStream)) { 1224 input2 = new BufferedInputStream(input2); 1225 } 1226 1227 int ch = input1.read(); 1228 while (-1 != ch) { 1229 int ch2 = input2.read(); 1230 if (ch != ch2) { 1231 return false; 1232 } 1233 ch = input1.read(); 1234 } 1235 1236 int ch2 = input2.read(); 1237 return (ch2 == -1); 1238 } 1239 1240 /** 1241 * Compare the contents of two Readers to determine if they are equal or 1242 * not. 1243 * <p> 1244 * This method buffers the input internally using 1245 * <code>BufferedReader</code> if they are not already buffered. 1246 * 1247 * @param input1 the first reader 1248 * @param input2 the second reader 1249 * @return true if the content of the readers are equal or they both don't 1250 * exist, false otherwise 1251 * @throws NullPointerException if either input is null 1252 * @throws IOException if an I/O error occurs 1253 * @since Commons IO 1.1 1254 */ contentEquals(Reader input1, Reader input2)1255 public static boolean contentEquals(Reader input1, Reader input2) 1256 throws IOException { 1257 if (!(input1 instanceof BufferedReader)) { 1258 input1 = new BufferedReader(input1); 1259 } 1260 if (!(input2 instanceof BufferedReader)) { 1261 input2 = new BufferedReader(input2); 1262 } 1263 1264 int ch = input1.read(); 1265 while (-1 != ch) { 1266 int ch2 = input2.read(); 1267 if (ch != ch2) { 1268 return false; 1269 } 1270 ch = input1.read(); 1271 } 1272 1273 int ch2 = input2.read(); 1274 return (ch2 == -1); 1275 } 1276 1277 } 1278