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