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 * https://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
18 package org.apache.commons.io;
19
20 import java.io.BufferedInputStream;
21 import java.io.BufferedOutputStream;
22 import java.io.BufferedReader;
23 import java.io.BufferedWriter;
24 import java.io.ByteArrayInputStream;
25 import java.io.CharArrayWriter;
26 import java.io.Closeable;
27 import java.io.EOFException;
28 import java.io.File;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.InputStreamReader;
32 import java.io.OutputStream;
33 import java.io.OutputStreamWriter;
34 import java.io.PipedInputStream;
35 import java.io.PipedOutputStream;
36 import java.io.Reader;
37 import java.io.UncheckedIOException;
38 import java.io.Writer;
39 import java.net.HttpURLConnection;
40 import java.net.ServerSocket;
41 import java.net.Socket;
42 import java.net.URI;
43 import java.net.URL;
44 import java.net.URLConnection;
45 import java.nio.ByteBuffer;
46 import java.nio.CharBuffer;
47 import java.nio.channels.Channels;
48 import java.nio.channels.ReadableByteChannel;
49 import java.nio.channels.Selector;
50 import java.nio.charset.Charset;
51 import java.nio.charset.StandardCharsets;
52 import java.nio.file.Files;
53 import java.util.Arrays;
54 import java.util.Collection;
55 import java.util.Iterator;
56 import java.util.List;
57 import java.util.Objects;
58 import java.util.function.Consumer;
59 import java.util.function.Supplier;
60 import java.util.stream.Collectors;
61 import java.util.stream.Stream;
62 import java.util.zip.InflaterInputStream;
63
64 import org.apache.commons.io.channels.FileChannels;
65 import org.apache.commons.io.function.IOConsumer;
66 import org.apache.commons.io.function.IOSupplier;
67 import org.apache.commons.io.function.IOTriFunction;
68 import org.apache.commons.io.input.BoundedInputStream;
69 import org.apache.commons.io.input.CharSequenceReader;
70 import org.apache.commons.io.input.QueueInputStream;
71 import org.apache.commons.io.output.AppendableWriter;
72 import org.apache.commons.io.output.ByteArrayOutputStream;
73 import org.apache.commons.io.output.NullOutputStream;
74 import org.apache.commons.io.output.NullWriter;
75 import org.apache.commons.io.output.StringBuilderWriter;
76 import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
77
78 /**
79 * General IO stream manipulation utilities.
80 * <p>
81 * This class provides static utility methods for input/output operations.
82 * </p>
83 * <ul>
84 * <li>closeQuietly - these methods close a stream ignoring nulls and exceptions
85 * <li>toXxx/read - these methods read data from a stream
86 * <li>write - these methods write data to a stream
87 * <li>copy - these methods copy all the data from one stream to another
88 * <li>contentEquals - these methods compare the content of two streams
89 * </ul>
90 * <p>
91 * The byte-to-char methods and char-to-byte methods involve a conversion step.
92 * Two methods are provided in each case, one that uses the platform default
93 * encoding and the other which allows you to specify an encoding. You are
94 * encouraged to always specify an encoding because relying on the platform
95 * default can lead to unexpected results, for example when moving from
96 * development to production.
97 * </p>
98 * <p>
99 * All the methods in this class that read a stream are buffered internally.
100 * This means that there is no cause to use a {@link BufferedInputStream}
101 * or {@link BufferedReader}. The default buffer size of 4K has been shown
102 * to be efficient in tests.
103 * </p>
104 * <p>
105 * The various copy methods all delegate the actual copying to one of the following methods:
106 * </p>
107 * <ul>
108 * <li>{@link #copyLarge(InputStream, OutputStream, byte[])}</li>
109 * <li>{@link #copyLarge(InputStream, OutputStream, long, long, byte[])}</li>
110 * <li>{@link #copyLarge(Reader, Writer, char[])}</li>
111 * <li>{@link #copyLarge(Reader, Writer, long, long, char[])}</li>
112 * </ul>
113 * For example, {@link #copy(InputStream, OutputStream)} calls {@link #copyLarge(InputStream, OutputStream)}
114 * which calls {@link #copy(InputStream, OutputStream, int)} which creates the buffer and calls
115 * {@link #copyLarge(InputStream, OutputStream, byte[])}.
116 * <p>
117 * Applications can re-use buffers by using the underlying methods directly.
118 * This may improve performance for applications that need to do a lot of copying.
119 * </p>
120 * <p>
121 * Wherever possible, the methods in this class do <em>not</em> flush or close
122 * the stream. This is to avoid making non-portable assumptions about the
123 * streams' origin and further use. Thus the caller is still responsible for
124 * closing streams after use.
125 * </p>
126 * <p>
127 * Provenance: Excalibur.
128 * </p>
129 */
130 public class IOUtils {
131 // NOTE: This class is focused on InputStream, OutputStream, Reader and
132 // Writer. Each method should take at least one of these as a parameter,
133 // or return one of them.
134
135 /**
136 * Holder for per-thread internal scratch buffer.
137 *
138 * <p>Buffers are created lazily and reused within the same thread to reduce allocation overhead. In the rare case of reentrant access, a temporary buffer
139 * is allocated to avoid data corruption.</p>
140 *
141 * <p>Typical usage:</p>
142 *
143 * <pre>{@code
144 * try (ScratchBytes scratch = ScratchBytes.get()) {
145 * // use the buffer
146 * byte[] bytes = scratch.array();
147 * // ...
148 * }
149 * }</pre>
150 */
151 static final class ScratchBytes implements AutoCloseable {
152
153 /**
154 * Wraps an internal byte array.
155 *
156 * [0] boolean in use.
157 * [1] byte[] buffer.
158 */
159 private static final ThreadLocal<Object[]> LOCAL = ThreadLocal.withInitial(() -> new Object[] { false, byteArray() });
160
161 private static final ScratchBytes INSTANCE = new ScratchBytes(null);
162
163 /**
164 * Gets the internal byte array buffer.
165 *
166 * @return the internal byte array buffer.
167 */
168 static ScratchBytes get() {
169 final Object[] holder = LOCAL.get();
170 // If already in use, return a new array
171 if ((boolean) holder[0]) {
172 return new ScratchBytes(byteArray());
173 }
174 holder[0] = true;
175 return INSTANCE;
176 }
177
178 /**
179 * The buffer, or null if using the thread-local buffer.
180 */
181 private final byte[] buffer;
182
183 private ScratchBytes(final byte[] buffer) {
184 this.buffer = buffer;
185 }
186
187 byte[] array() {
188 return buffer != null ? buffer : (byte[]) LOCAL.get()[1];
189 }
190
191 /**
192 * If the buffer is the internal array, clear and release it for reuse.
193 */
194 @Override
195 public void close() {
196 if (buffer == null) {
197 final Object[] holder = LOCAL.get();
198 Arrays.fill((byte[]) holder[1], (byte) 0);
199 holder[0] = false;
200 }
201 }
202 }
203
204 /**
205 * Holder for per-thread internal scratch buffer.
206 *
207 * <p>Buffers are created lazily and reused within the same thread to reduce allocation overhead. In the rare case of reentrant access, a temporary buffer
208 * is allocated to avoid data corruption.</p>
209 *
210 * <p>Typical usage:</p>
211 *
212 * <pre>{@code
213 * try (ScratchChars scratch = ScratchChars.get()) {
214 * // use the buffer
215 * char[] bytes = scratch.array();
216 * // ...
217 * }
218 * }</pre>
219 */
220 static final class ScratchChars implements AutoCloseable {
221
222 /**
223 * Wraps an internal char array.
224 *
225 * [0] boolean in use.
226 * [1] char[] buffer.
227 */
228 private static final ThreadLocal<Object[]> LOCAL = ThreadLocal.withInitial(() -> new Object[] { false, charArray() });
229
230 private static final ScratchChars INSTANCE = new ScratchChars(null);
231
232 /**
233 * Gets the internal char array buffer.
234 *
235 * @return the internal char array buffer.
236 */
237 static ScratchChars get() {
238 final Object[] holder = LOCAL.get();
239 // If already in use, return a new array
240 if ((boolean) holder[0]) {
241 return new ScratchChars(charArray());
242 }
243 holder[0] = true;
244 return INSTANCE;
245 }
246
247 /**
248 * The buffer, or null if using the thread-local buffer.
249 */
250 private final char[] buffer;
251
252 private ScratchChars(final char[] buffer) {
253 this.buffer = buffer;
254 }
255
256 char[] array() {
257 return buffer != null ? buffer : (char[]) LOCAL.get()[1];
258 }
259
260 /**
261 * If the buffer is the internal array, clear and release it for reuse.
262 */
263 @Override
264 public void close() {
265 if (buffer == null) {
266 final Object[] holder = LOCAL.get();
267 Arrays.fill((char[]) holder[1], (char) 0);
268 holder[0] = false;
269 }
270 }
271 }
272
273 /**
274 * CR char '{@value}'.
275 *
276 * @since 2.9.0
277 */
278 public static final int CR = '\r';
279
280 /**
281 * The default buffer size ({@value}) to use in copy methods.
282 */
283 public static final int DEFAULT_BUFFER_SIZE = 8192;
284
285 /**
286 * The system directory separator character.
287 */
288 public static final char DIR_SEPARATOR = File.separatorChar;
289
290 /**
291 * The Unix directory separator character '{@value}'.
292 */
293 public static final char DIR_SEPARATOR_UNIX = '/';
294
295 /**
296 * The Windows directory separator character '{@value}'.
297 */
298 public static final char DIR_SEPARATOR_WINDOWS = '\\';
299
300 /**
301 * A singleton empty byte array.
302 *
303 * @since 2.9.0
304 */
305 public static final byte[] EMPTY_BYTE_ARRAY = {};
306
307 /**
308 * Represents the end-of-file (or stream) value {@value}.
309 * @since 2.5 (made public)
310 */
311 public static final int EOF = -1;
312
313 /**
314 * LF char '{@value}'.
315 *
316 * @since 2.9.0
317 */
318 public static final int LF = '\n';
319
320 /**
321 * The system line separator string.
322 *
323 * @deprecated Use {@link System#lineSeparator()}.
324 */
325 @Deprecated
326 public static final String LINE_SEPARATOR = System.lineSeparator();
327
328 /**
329 * The Unix line separator string.
330 *
331 * @see StandardLineSeparator#LF
332 */
333 public static final String LINE_SEPARATOR_UNIX = StandardLineSeparator.LF.getString();
334
335 /**
336 * The Windows line separator string.
337 *
338 * @see StandardLineSeparator#CRLF
339 */
340 public static final String LINE_SEPARATOR_WINDOWS = StandardLineSeparator.CRLF.getString();
341
342 /**
343 * The maximum size of an array in many Java VMs.
344 * <p>
345 * The constant is copied from OpenJDK's {@code jdk.internal.util.ArraysSupport#SOFT_MAX_ARRAY_LENGTH}.
346 * </p>
347 *
348 * @since 2.21.0
349 */
350 public static final int SOFT_MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;
351
352 /**
353 * Returns the given InputStream if it is already a {@link BufferedInputStream}, otherwise creates a
354 * BufferedInputStream from the given InputStream.
355 *
356 * @param inputStream the InputStream to wrap or return (not null).
357 * @return the given InputStream or a new {@link BufferedInputStream} for the given InputStream.
358 * @throws NullPointerException if the input parameter is null.
359 * @since 2.5
360 */
361 @SuppressWarnings("resource") // parameter null check
362 public static BufferedInputStream buffer(final InputStream inputStream) {
363 // reject null early on rather than waiting for IO operation to fail
364 // not checked by BufferedInputStream
365 Objects.requireNonNull(inputStream, "inputStream");
366 return inputStream instanceof BufferedInputStream ?
367 (BufferedInputStream) inputStream : new BufferedInputStream(inputStream);
368 }
369
370 /**
371 * Returns the given InputStream if it is already a {@link BufferedInputStream}, otherwise creates a
372 * BufferedInputStream from the given InputStream.
373 *
374 * @param inputStream the InputStream to wrap or return (not null).
375 * @param size the buffer size, if a new BufferedInputStream is created.
376 * @return the given InputStream or a new {@link BufferedInputStream} for the given InputStream.
377 * @throws NullPointerException if the input parameter is null.
378 * @since 2.5
379 */
380 @SuppressWarnings("resource") // parameter null check
381 public static BufferedInputStream buffer(final InputStream inputStream, final int size) {
382 // reject null early on rather than waiting for IO operation to fail
383 // not checked by BufferedInputStream
384 Objects.requireNonNull(inputStream, "inputStream");
385 return inputStream instanceof BufferedInputStream ?
386 (BufferedInputStream) inputStream : new BufferedInputStream(inputStream, size);
387 }
388
389 /**
390 * Returns the given OutputStream if it is already a {@link BufferedOutputStream}, otherwise creates a
391 * BufferedOutputStream from the given OutputStream.
392 *
393 * @param outputStream the OutputStream to wrap or return (not null).
394 * @return the given OutputStream or a new {@link BufferedOutputStream} for the given OutputStream
395 * @throws NullPointerException if the input parameter is null.
396 * @since 2.5
397 */
398 @SuppressWarnings("resource") // parameter null check
399 public static BufferedOutputStream buffer(final OutputStream outputStream) {
400 // reject null early on rather than waiting for IO operation to fail
401 // not checked by BufferedInputStream
402 Objects.requireNonNull(outputStream, "outputStream");
403 return outputStream instanceof BufferedOutputStream ?
404 (BufferedOutputStream) outputStream : new BufferedOutputStream(outputStream);
405 }
406
407 /**
408 * Returns the given OutputStream if it is already a {@link BufferedOutputStream}, otherwise creates a
409 * BufferedOutputStream from the given OutputStream.
410 *
411 * @param outputStream the OutputStream to wrap or return (not null).
412 * @param size the buffer size, if a new BufferedOutputStream is created.
413 * @return the given OutputStream or a new {@link BufferedOutputStream} for the given OutputStream.
414 * @throws NullPointerException if the input parameter is null.
415 * @since 2.5
416 */
417 @SuppressWarnings("resource") // parameter null check
418 public static BufferedOutputStream buffer(final OutputStream outputStream, final int size) {
419 // reject null early on rather than waiting for IO operation to fail
420 // not checked by BufferedInputStream
421 Objects.requireNonNull(outputStream, "outputStream");
422 return outputStream instanceof BufferedOutputStream ?
423 (BufferedOutputStream) outputStream : new BufferedOutputStream(outputStream, size);
424 }
425
426 /**
427 * Returns the given reader if it is already a {@link BufferedReader}, otherwise creates a BufferedReader from
428 * the given reader.
429 *
430 * @param reader the reader to wrap or return (not null).
431 * @return the given reader or a new {@link BufferedReader} for the given reader.
432 * @throws NullPointerException if the input parameter is null.
433 * @since 2.5
434 */
435 public static BufferedReader buffer(final Reader reader) {
436 return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
437 }
438
439 /**
440 * Returns the given reader if it is already a {@link BufferedReader}, otherwise creates a BufferedReader from the
441 * given reader.
442 *
443 * @param reader the reader to wrap or return (not null).
444 * @param size the buffer size, if a new BufferedReader is created.
445 * @return the given reader or a new {@link BufferedReader} for the given reader.
446 * @throws NullPointerException if the input parameter is null.
447 * @since 2.5
448 */
449 public static BufferedReader buffer(final Reader reader, final int size) {
450 return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader, size);
451 }
452
453 /**
454 * Returns the given Writer if it is already a {@link BufferedWriter}, otherwise creates a BufferedWriter from the
455 * given Writer.
456 *
457 * @param writer the Writer to wrap or return (not null).
458 * @return the given Writer or a new {@link BufferedWriter} for the given Writer.
459 * @throws NullPointerException if the input parameter is null.
460 * @since 2.5
461 */
462 public static BufferedWriter buffer(final Writer writer) {
463 return writer instanceof BufferedWriter ? (BufferedWriter) writer : new BufferedWriter(writer);
464 }
465
466 /**
467 * Returns the given Writer if it is already a {@link BufferedWriter}, otherwise creates a BufferedWriter from the
468 * given Writer.
469 *
470 * @param writer the Writer to wrap or return (not null).
471 * @param size the buffer size, if a new BufferedWriter is created.
472 * @return the given Writer or a new {@link BufferedWriter} for the given Writer.
473 * @throws NullPointerException if the input parameter is null.
474 * @since 2.5
475 */
476 public static BufferedWriter buffer(final Writer writer, final int size) {
477 return writer instanceof BufferedWriter ? (BufferedWriter) writer : new BufferedWriter(writer, size);
478 }
479
480 /**
481 * Returns a new byte array of size {@link #DEFAULT_BUFFER_SIZE}.
482 *
483 * @return a new byte array of size {@link #DEFAULT_BUFFER_SIZE}.
484 * @since 2.9.0
485 */
486 public static byte[] byteArray() {
487 return byteArray(DEFAULT_BUFFER_SIZE);
488 }
489
490 /**
491 * Returns a new byte array of the given size.
492 *
493 * TODO Consider guarding or warning against large allocations.
494 *
495 * @param size array size.
496 * @return a new byte array of the given size.
497 * @throws NegativeArraySizeException if the size is negative.
498 * @since 2.9.0
499 */
500 public static byte[] byteArray(final int size) {
501 return new byte[size];
502 }
503
504 /**
505 * Returns a new char array of size {@link #DEFAULT_BUFFER_SIZE}.
506 *
507 * @return a new char array of size {@link #DEFAULT_BUFFER_SIZE}.
508 * @since 2.9.0
509 */
510 private static char[] charArray() {
511 return charArray(DEFAULT_BUFFER_SIZE);
512 }
513
514 /**
515 * Returns a new char array of the given size.
516 *
517 * TODO Consider guarding or warning against large allocations.
518 *
519 * @param size array size.
520 * @return a new char array of the given size.
521 * @since 2.9.0
522 */
523 private static char[] charArray(final int size) {
524 return new char[size];
525 }
526
527 /**
528 * Validates that the sub-range {@code [off, off + len)} is within the bounds of the given array.
529 *
530 * <p>The range is valid if all of the following hold:</p>
531 * <ul>
532 * <li>{@code off >= 0}</li>
533 * <li>{@code len >= 0}</li>
534 * <li>{@code off + len <= array.length}</li>
535 * </ul>
536 *
537 * <p>If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.</p>
538 *
539 * <p>Typical usage in {@link InputStream#read(byte[], int, int)} and {@link OutputStream#write(byte[], int, int)} implementations:</p>
540 *
541 * <pre><code>
542 * public int read(byte[] b, int off, int len) throws IOException {
543 * IOUtils.checkFromIndexSize(b, off, len);
544 * if (len == 0) {
545 * return 0;
546 * }
547 * ensureOpen();
548 * // perform read...
549 * }
550 *
551 * public void write(byte[] b, int off, int len) throws IOException {
552 * IOUtils.checkFromIndexSize(b, off, len);
553 * if (len == 0) {
554 * return;
555 * }
556 * ensureOpen();
557 * // perform write...
558 * }
559 * </code></pre>
560 *
561 * @param array the array against which the range is validated
562 * @param off the starting offset into the array (inclusive)
563 * @param len the number of elements to access
564 * @throws NullPointerException if {@code array} is {@code null}
565 * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code array}
566 * @see InputStream#read(byte[], int, int)
567 * @see OutputStream#write(byte[], int, int)
568 * @since 2.21.0
569 */
570 public static void checkFromIndexSize(final byte[] array, final int off, final int len) {
571 checkFromIndexSize(off, len, Objects.requireNonNull(array, "byte array").length);
572 }
573
574 /**
575 * Validates that the sub-range {@code [off, off + len)} is within the bounds of the given array.
576 *
577 * <p>The range is valid if all of the following hold:</p>
578 * <ul>
579 * <li>{@code off >= 0}</li>
580 * <li>{@code len >= 0}</li>
581 * <li>{@code off + len <= array.length}</li>
582 * </ul>
583 *
584 * <p>If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.</p>
585 *
586 * <p>Typical usage in {@link Reader#read(char[], int, int)} and {@link Writer#write(char[], int, int)} implementations:</p>
587 *
588 * <pre><code>
589 * public int read(char[] cbuf, int off, int len) throws IOException {
590 * ensureOpen();
591 * IOUtils.checkFromIndexSize(cbuf, off, len);
592 * if (len == 0) {
593 * return 0;
594 * }
595 * // perform read...
596 * }
597 *
598 * public void write(char[] cbuf, int off, int len) throws IOException {
599 * ensureOpen();
600 * IOUtils.checkFromIndexSize(cbuf, off, len);
601 * if (len == 0) {
602 * return;
603 * }
604 * // perform write...
605 * }
606 * </code></pre>
607 *
608 * @param array the array against which the range is validated
609 * @param off the starting offset into the array (inclusive)
610 * @param len the number of characters to access
611 * @throws NullPointerException if {@code array} is {@code null}
612 * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code array}
613 * @see Reader#read(char[], int, int)
614 * @see Writer#write(char[], int, int)
615 * @since 2.21.0
616 */
617 public static void checkFromIndexSize(final char[] array, final int off, final int len) {
618 checkFromIndexSize(off, len, Objects.requireNonNull(array, "char array").length);
619 }
620
621 static void checkFromIndexSize(final int off, final int len, final int arrayLength) {
622 if ((off | len | arrayLength) < 0 || arrayLength - len < off) {
623 throw new IndexOutOfBoundsException(String.format("Range [%s, %<s + %s) out of bounds for length %s", off, len, arrayLength));
624 }
625 }
626
627 /**
628 * Validates that the sub-range {@code [off, off + len)} is within the bounds of the given string.
629 *
630 * <p>The range is valid if all of the following hold:</p>
631 * <ul>
632 * <li>{@code off >= 0}</li>
633 * <li>{@code len >= 0}</li>
634 * <li>{@code off + len <= str.length()}</li>
635 * </ul>
636 *
637 * <p>If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.</p>
638 *
639 * <p>Typical usage in {@link Writer#write(String, int, int)} implementations:</p>
640 *
641 * <pre><code>
642 * public void write(String str, int off, int len) throws IOException {
643 * IOUtils.checkFromIndexSize(str, off, len);
644 * if (len == 0) {
645 * return;
646 * }
647 * // perform write...
648 * }
649 * </code></pre>
650 *
651 * @param str the string against which the range is validated
652 * @param off the starting offset into the string (inclusive)
653 * @param len the number of characters to write
654 * @throws NullPointerException if {@code str} is {@code null}
655 * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code str}
656 * @see Writer#write(String, int, int)
657 * @since 2.21.0
658 */
659 public static void checkFromIndexSize(final String str, final int off, final int len) {
660 checkFromIndexSize(off, len, Objects.requireNonNull(str, "str").length());
661 }
662
663 /**
664 * Validates that the sub-sequence {@code [fromIndex, toIndex)} is within the bounds of the given {@link CharSequence}.
665 *
666 * <p>The sub-sequence is valid if all of the following hold:</p>
667 * <ul>
668 * <li>{@code fromIndex >= 0}</li>
669 * <li>{@code fromIndex <= toIndex}</li>
670 * <li>{@code toIndex <= seq.length()}</li>
671 * </ul>
672 *
673 * <p>If {@code seq} is {@code null}, it is treated as the literal string {@code "null"} (length {@code 4}).</p>
674 *
675 * <p>If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.</p>
676 *
677 * <p>Typical usage in {@link Appendable#append(CharSequence, int, int)} implementations:</p>
678 *
679 * <pre><code>
680 * public Appendable append(CharSequence csq, int start, int end) throws IOException {
681 * IOUtils.checkFromToIndex(csq, start, end);
682 * // perform append...
683 * return this;
684 * }
685 * </code></pre>
686 *
687 * @param seq the character sequence to validate (may be {@code null}, treated as {@code "null"})
688 * @param fromIndex the starting index (inclusive)
689 * @param toIndex the ending index (exclusive)
690 * @throws IndexOutOfBoundsException if the range {@code [fromIndex, toIndex)} is out of bounds for {@code seq}
691 * @see Appendable#append(CharSequence, int, int)
692 * @since 2.21.0
693 */
694 public static void checkFromToIndex(final CharSequence seq, final int fromIndex, final int toIndex) {
695 checkFromToIndex(fromIndex, toIndex, seq != null ? seq.length() : 4);
696 }
697
698 static void checkFromToIndex(final int fromIndex, final int toIndex, final int length) {
699 if (fromIndex < 0 || toIndex < fromIndex || length < toIndex) {
700 throw new IndexOutOfBoundsException(String.format("Range [%s, %s) out of bounds for length %s", fromIndex, toIndex, length));
701 }
702 }
703
704 /**
705 * Clears any state.
706 * <ul>
707 * <li>Removes the current thread's value for thread-local variables.</li>
708 * <li>Sets static scratch arrays to 0s.</li>
709 * </ul>
710 * @see IO#clear()
711 */
712 static void clear() {
713 ScratchBytes.LOCAL.remove();
714 ScratchChars.LOCAL.remove();
715 }
716
717 /**
718 * Closes the given {@link Closeable} as a null-safe operation.
719 *
720 * @param closeable The resource to close, may be null.
721 * @throws IOException if an I/O error occurs.
722 * @since 2.7
723 */
724 public static void close(final Closeable closeable) throws IOException {
725 if (closeable != null) {
726 closeable.close();
727 }
728 }
729
730 /**
731 * Closes the given {@link Closeable}s as null-safe operations.
732 *
733 * @param closeables The resource(s) to close, may be null.
734 * @throws IOExceptionList if an I/O error occurs.
735 * @since 2.8.0
736 */
737 public static void close(final Closeable... closeables) throws IOExceptionList {
738 IOConsumer.forAll(IOUtils::close, closeables);
739 }
740
741 /**
742 * Closes the given {@link Closeable} as a null-safe operation.
743 *
744 * @param closeable The resource to close, may be null.
745 * @param consumer Consume the IOException thrown by {@link Closeable#close()}.
746 * @throws IOException if an I/O error occurs.
747 * @since 2.7
748 */
749 public static void close(final Closeable closeable, final IOConsumer<IOException> consumer) throws IOException {
750 if (closeable != null) {
751 try {
752 closeable.close();
753 } catch (final IOException e) {
754 if (consumer != null) {
755 consumer.accept(e);
756 }
757 } catch (final Exception e) {
758 if (consumer != null) {
759 consumer.accept(new IOException(e));
760 }
761 }
762 }
763 }
764
765 /**
766 * Closes a URLConnection.
767 *
768 * @param conn the connection to close.
769 * @since 2.4
770 */
771 public static void close(final URLConnection conn) {
772 if (conn instanceof HttpURLConnection) {
773 ((HttpURLConnection) conn).disconnect();
774 }
775 }
776
777 /**
778 * Avoids the need to type cast.
779 *
780 * @param closeable the object to close, may be null.
781 */
782 private static void closeQ(final Closeable closeable) {
783 closeQuietly(closeable, null);
784 }
785
786 /**
787 * Closes a {@link Closeable} unconditionally.
788 *
789 * <p>
790 * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored. This is typically used in
791 * finally blocks.
792 * <p>
793 * Example code:
794 * </p>
795 * <pre>
796 * Closeable closeable = null;
797 * try {
798 * closeable = new FileReader("foo.txt");
799 * // process closeable
800 * closeable.close();
801 * } catch (Exception e) {
802 * // error handling
803 * } finally {
804 * IOUtils.closeQuietly(closeable);
805 * }
806 * </pre>
807 * <p>
808 * Closing all streams:
809 * </p>
810 * <pre>
811 * try {
812 * return IOUtils.copy(inputStream, outputStream);
813 * } finally {
814 * IOUtils.closeQuietly(inputStream);
815 * IOUtils.closeQuietly(outputStream);
816 * }
817 * </pre>
818 * <p>
819 * Also consider using a try-with-resources statement where appropriate.
820 * </p>
821 *
822 * @param closeable the objects to close, may be null or already closed.
823 * @since 2.0
824 * @see Throwable#addSuppressed(Throwable)
825 */
826 public static void closeQuietly(final Closeable closeable) {
827 closeQuietly(closeable, null);
828 }
829
830 /**
831 * Closes a {@link Closeable} unconditionally.
832 * <p>
833 * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored.
834 * <p>
835 * This is typically used in finally blocks to ensure that the closeable is closed
836 * even if an Exception was thrown before the normal close statement was reached.
837 * <br>
838 * <b>It should not be used to replace the close statement(s)
839 * which should be present for the non-exceptional case.</b>
840 * <br>
841 * It is only intended to simplify tidying up where normal processing has already failed
842 * and reporting close failure as well is not necessary or useful.
843 * <p>
844 * Example code:
845 * </p>
846 * <pre>
847 * Closeable closeable = null;
848 * try {
849 * closeable = new FileReader("foo.txt");
850 * // processing using the closeable; may throw an Exception
851 * closeable.close(); // Normal close - exceptions not ignored
852 * } catch (Exception e) {
853 * // error handling
854 * } finally {
855 * <strong>IOUtils.closeQuietly(closeable); // In case normal close was skipped due to Exception</strong>
856 * }
857 * </pre>
858 * <p>
859 * Closing all streams:
860 * <br>
861 * <pre>
862 * try {
863 * return IOUtils.copy(inputStream, outputStream);
864 * } finally {
865 * IOUtils.closeQuietly(inputStream, outputStream);
866 * }
867 * </pre>
868 * <p>
869 * Also consider using a try-with-resources statement where appropriate.
870 * </p>
871 * @param closeables the objects to close, may be null or already closed.
872 * @see #closeQuietly(Closeable)
873 * @since 2.5
874 * @see Throwable#addSuppressed(Throwable)
875 */
876 public static void closeQuietly(final Closeable... closeables) {
877 if (closeables != null) {
878 closeQuietly(Arrays.stream(closeables));
879 }
880 }
881
882 /**
883 * Closes the given {@link Closeable} as a null-safe operation while consuming IOException by the given {@code consumer}.
884 *
885 * @param closeable The resource to close, may be null.
886 * @param consumer Consumes the Exception thrown by {@link Closeable#close()}.
887 * @since 2.7
888 */
889 public static void closeQuietly(final Closeable closeable, final Consumer<Exception> consumer) {
890 if (closeable != null) {
891 try {
892 closeable.close();
893 } catch (final Exception e) {
894 if (consumer != null) {
895 consumer.accept(e);
896 }
897 }
898 }
899 }
900
901 /**
902 * Closes an {@link InputStream} unconditionally.
903 * <p>
904 * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored.
905 * This is typically used in finally blocks.
906 * </p>
907 * <p>
908 * Example code:
909 * </p>
910 * <pre>
911 * byte[] data = new byte[1024];
912 * InputStream in = null;
913 * try {
914 * in = new FileInputStream("foo.txt");
915 * in.read(data);
916 * in.close(); //close errors are handled
917 * } catch (Exception e) {
918 * // error handling
919 * } finally {
920 * IOUtils.closeQuietly(in);
921 * }
922 * </pre>
923 * <p>
924 * Also consider using a try-with-resources statement where appropriate.
925 * </p>
926 *
927 * @param input the InputStream to close, may be null or already closed.
928 * @see Throwable#addSuppressed(Throwable)
929 */
930 public static void closeQuietly(final InputStream input) {
931 closeQ(input);
932 }
933
934 /**
935 * Closes an iterable of {@link Closeable} unconditionally.
936 * <p>
937 * Equivalent calling {@link Closeable#close()} on each element, except any exceptions will be ignored.
938 * </p>
939 *
940 * @param closeables the objects to close, may be null or already closed.
941 * @see #closeQuietly(Closeable)
942 * @since 2.12.0
943 */
944 public static void closeQuietly(final Iterable<Closeable> closeables) {
945 if (closeables != null) {
946 closeables.forEach(IOUtils::closeQuietly);
947 }
948 }
949
950 /**
951 * Closes an {@link OutputStream} unconditionally.
952 * <p>
953 * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored.
954 * This is typically used in finally blocks.
955 * </p>
956 * <p>
957 * Example code:
958 * </p>
959 * <pre>
960 * byte[] data = "Hello, World".getBytes();
961 *
962 * OutputStream out = null;
963 * try {
964 * out = new FileOutputStream("foo.txt");
965 * out.write(data);
966 * out.close(); //close errors are handled
967 * } catch (IOException e) {
968 * // error handling
969 * } finally {
970 * IOUtils.closeQuietly(out);
971 * }
972 * </pre>
973 * <p>
974 * Also consider using a try-with-resources statement where appropriate.
975 * </p>
976 *
977 * @param output the OutputStream to close, may be null or already closed.
978 * @see Throwable#addSuppressed(Throwable)
979 */
980 public static void closeQuietly(final OutputStream output) {
981 closeQ(output);
982 }
983
984 /**
985 * Closes an {@link Reader} unconditionally.
986 * <p>
987 * Equivalent to {@link Reader#close()}, except any exceptions will be ignored.
988 * This is typically used in finally blocks.
989 * </p>
990 * <p>
991 * Example code:
992 * </p>
993 * <pre>
994 * char[] data = new char[1024];
995 * Reader in = null;
996 * try {
997 * in = new FileReader("foo.txt");
998 * in.read(data);
999 * in.close(); //close errors are handled
1000 * } catch (Exception e) {
1001 * // error handling
1002 * } finally {
1003 * IOUtils.closeQuietly(in);
1004 * }
1005 * </pre>
1006 * <p>
1007 * Also consider using a try-with-resources statement where appropriate.
1008 * </p>
1009 *
1010 * @param reader the Reader to close, may be null or already closed.
1011 * @see Throwable#addSuppressed(Throwable)
1012 */
1013 public static void closeQuietly(final Reader reader) {
1014 closeQ(reader);
1015 }
1016
1017 /**
1018 * Closes a {@link Selector} unconditionally.
1019 * <p>
1020 * Equivalent to {@link Selector#close()}, except any exceptions will be ignored.
1021 * This is typically used in finally blocks.
1022 * </p>
1023 * <p>
1024 * Example code:
1025 * </p>
1026 * <pre>
1027 * Selector selector = null;
1028 * try {
1029 * selector = Selector.open();
1030 * // process socket
1031 *
1032 * } catch (Exception e) {
1033 * // error handling
1034 * } finally {
1035 * IOUtils.closeQuietly(selector);
1036 * }
1037 * </pre>
1038 * <p>
1039 * Also consider using a try-with-resources statement where appropriate.
1040 * </p>
1041 *
1042 * @param selector the Selector to close, may be null or already closed.
1043 * @since 2.2
1044 * @see Throwable#addSuppressed(Throwable)
1045 */
1046 public static void closeQuietly(final Selector selector) {
1047 closeQ(selector);
1048 }
1049
1050 /**
1051 * Closes a {@link ServerSocket} unconditionally.
1052 * <p>
1053 * Equivalent to {@link ServerSocket#close()}, except any exceptions will be ignored.
1054 * This is typically used in finally blocks.
1055 * </p>
1056 * <p>
1057 * Example code:
1058 * </p>
1059 * <pre>
1060 * ServerSocket socket = null;
1061 * try {
1062 * socket = new ServerSocket();
1063 * // process socket
1064 * socket.close();
1065 * } catch (Exception e) {
1066 * // error handling
1067 * } finally {
1068 * IOUtils.closeQuietly(socket);
1069 * }
1070 * </pre>
1071 * <p>
1072 * Also consider using a try-with-resources statement where appropriate.
1073 * </p>
1074 *
1075 * @param serverSocket the ServerSocket to close, may be null or already closed.
1076 * @since 2.2
1077 * @see Throwable#addSuppressed(Throwable)
1078 */
1079 public static void closeQuietly(final ServerSocket serverSocket) {
1080 closeQ(serverSocket);
1081 }
1082
1083 /**
1084 * Closes a {@link Socket} unconditionally.
1085 * <p>
1086 * Equivalent to {@link Socket#close()}, except any exceptions will be ignored.
1087 * This is typically used in finally blocks.
1088 * </p>
1089 * <p>
1090 * Example code:
1091 * </p>
1092 * <pre>
1093 * Socket socket = null;
1094 * try {
1095 * socket = new Socket("http://www.foo.com/", 80);
1096 * // process socket
1097 * socket.close();
1098 * } catch (Exception e) {
1099 * // error handling
1100 * } finally {
1101 * IOUtils.closeQuietly(socket);
1102 * }
1103 * </pre>
1104 * <p>
1105 * Also consider using a try-with-resources statement where appropriate.
1106 * </p>
1107 *
1108 * @param socket the Socket to close, may be null or already closed.
1109 * @since 2.0
1110 * @see Throwable#addSuppressed(Throwable)
1111 */
1112 public static void closeQuietly(final Socket socket) {
1113 closeQ(socket);
1114 }
1115
1116 /**
1117 * Closes a stream of {@link Closeable} unconditionally.
1118 * <p>
1119 * Equivalent calling {@link Closeable#close()} on each element, except any exceptions will be ignored.
1120 * </p>
1121 *
1122 * @param closeables the objects to close, may be null or already closed.
1123 * @see #closeQuietly(Closeable)
1124 * @since 2.12.0
1125 */
1126 public static void closeQuietly(final Stream<Closeable> closeables) {
1127 if (closeables != null) {
1128 closeables.forEach(IOUtils::closeQuietly);
1129 }
1130 }
1131
1132 /**
1133 * Closes an {@link Writer} unconditionally.
1134 * <p>
1135 * Equivalent to {@link Writer#close()}, except any exceptions will be ignored.
1136 * This is typically used in finally blocks.
1137 * </p>
1138 * <p>
1139 * Example code:
1140 * </p>
1141 * <pre>
1142 * Writer out = null;
1143 * try {
1144 * out = new StringWriter();
1145 * out.write("Hello World");
1146 * out.close(); //close errors are handled
1147 * } catch (Exception e) {
1148 * // error handling
1149 * } finally {
1150 * IOUtils.closeQuietly(out);
1151 * }
1152 * </pre>
1153 * <p>
1154 * Also consider using a try-with-resources statement where appropriate.
1155 * </p>
1156 *
1157 * @param writer the Writer to close, may be null or already closed.
1158 * @see Throwable#addSuppressed(Throwable)
1159 */
1160 public static void closeQuietly(final Writer writer) {
1161 closeQ(writer);
1162 }
1163
1164 /**
1165 * Consumes bytes from a {@link InputStream} and ignores them.
1166 * <p>
1167 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1168 * </p>
1169 *
1170 * @param input the {@link InputStream} to read.
1171 * @return the number of bytes copied. or {@code 0} if {@code input is null}.
1172 * @throws NullPointerException if the InputStream is {@code null}.
1173 * @throws IOException if an I/O error occurs.
1174 * @since 2.8.0
1175 */
1176 public static long consume(final InputStream input) throws IOException {
1177 return copyLarge(input, NullOutputStream.INSTANCE);
1178 }
1179
1180 /**
1181 * Consumes characters from a {@link Reader} and ignores them.
1182 * <p>
1183 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1184 * </p>
1185 *
1186 * @param input the {@link Reader} to read.
1187 * @return the number of bytes copied. or {@code 0} if {@code input is null}.
1188 * @throws NullPointerException if the Reader is {@code null}.
1189 * @throws IOException if an I/O error occurs.
1190 * @since 2.12.0
1191 */
1192 public static long consume(final Reader input) throws IOException {
1193 return copyLarge(input, NullWriter.INSTANCE);
1194 }
1195
1196 /**
1197 * Compares the contents of two Streams to determine if they are equal or
1198 * not.
1199 * <p>
1200 * This method buffers the input internally using
1201 * {@link BufferedInputStream} if they are not already buffered.
1202 * </p>
1203 *
1204 * @param input1 the first stream.
1205 * @param input2 the second stream.
1206 * @return true if the content of the streams are equal or they both don't.
1207 * exist, false otherwise.
1208 * @throws IOException if an I/O error occurs.
1209 */
1210 @SuppressWarnings("resource") // Caller closes input streams
1211 public static boolean contentEquals(final InputStream input1, final InputStream input2) throws IOException {
1212 // Before making any changes, please test with org.apache.commons.io.jmh.IOUtilsContentEqualsInputStreamsBenchmark
1213 if (input1 == input2) {
1214 return true;
1215 }
1216 if (input1 == null || input2 == null) {
1217 return false;
1218 }
1219 // We do not close FileChannels because that closes the owning InputStream.
1220 return FileChannels.contentEquals(Channels.newChannel(input1), Channels.newChannel(input2), DEFAULT_BUFFER_SIZE);
1221 }
1222
1223 // TODO Consider making public
1224 private static boolean contentEquals(final Iterator<?> iterator1, final Iterator<?> iterator2) {
1225 while (iterator1.hasNext()) {
1226 if (!iterator2.hasNext()) {
1227 return false;
1228 }
1229 if (!Objects.equals(iterator1.next(), iterator2.next())) {
1230 return false;
1231 }
1232 }
1233 return !iterator2.hasNext();
1234 }
1235
1236 /**
1237 * Compares the contents of two Readers to determine if they are equal or not.
1238 * <p>
1239 * This method buffers the input internally using {@link BufferedReader} if they are not already buffered.
1240 * </p>
1241 *
1242 * @param input1 the first reader.
1243 * @param input2 the second reader.
1244 * @return true if the content of the readers are equal or they both don't exist, false otherwise.
1245 * @throws NullPointerException if either input is null.
1246 * @throws IOException if an I/O error occurs.
1247 * @since 1.1
1248 */
1249 public static boolean contentEquals(final Reader input1, final Reader input2) throws IOException {
1250 if (input1 == input2) {
1251 return true;
1252 }
1253 if (input1 == null || input2 == null) {
1254 return false;
1255 }
1256
1257 // reuse one
1258 try (ScratchChars scratch = IOUtils.ScratchChars.get()) {
1259 final char[] array1 = scratch.array();
1260 // but allocate another
1261 final char[] array2 = charArray();
1262 int pos1;
1263 int pos2;
1264 int count1;
1265 int count2;
1266 while (true) {
1267 pos1 = 0;
1268 pos2 = 0;
1269 for (int index = 0; index < DEFAULT_BUFFER_SIZE; index++) {
1270 if (pos1 == index) {
1271 do {
1272 count1 = input1.read(array1, pos1, DEFAULT_BUFFER_SIZE - pos1);
1273 } while (count1 == 0);
1274 if (count1 == EOF) {
1275 return pos2 == index && input2.read() == EOF;
1276 }
1277 pos1 += count1;
1278 }
1279 if (pos2 == index) {
1280 do {
1281 count2 = input2.read(array2, pos2, DEFAULT_BUFFER_SIZE - pos2);
1282 } while (count2 == 0);
1283 if (count2 == EOF) {
1284 return pos1 == index && input1.read() == EOF;
1285 }
1286 pos2 += count2;
1287 }
1288 if (array1[index] != array2[index]) {
1289 return false;
1290 }
1291 }
1292 }
1293 }
1294 }
1295
1296 // TODO Consider making public
1297 private static boolean contentEquals(final Stream<?> stream1, final Stream<?> stream2) {
1298 if (stream1 == stream2) {
1299 return true;
1300 }
1301 if (stream1 == null || stream2 == null) {
1302 return false;
1303 }
1304 return contentEquals(stream1.iterator(), stream2.iterator());
1305 }
1306
1307 // TODO Consider making public
1308 private static boolean contentEqualsIgnoreEOL(final BufferedReader reader1, final BufferedReader reader2) {
1309 if (reader1 == reader2) {
1310 return true;
1311 }
1312 if (reader1 == null || reader2 == null) {
1313 return false;
1314 }
1315 return contentEquals(reader1.lines(), reader2.lines());
1316 }
1317
1318 /**
1319 * Compares the contents of two Readers to determine if they are equal or
1320 * not, ignoring EOL characters.
1321 * <p>
1322 * This method buffers the input internally using
1323 * {@link BufferedReader} if they are not already buffered.
1324 * </p>
1325 *
1326 * @param reader1 the first reader.
1327 * @param reader2 the second reader.
1328 * @return true if the content of the readers are equal (ignoring EOL differences), false otherwise.
1329 * @throws NullPointerException if either input is null.
1330 * @throws UncheckedIOException if an I/O error occurs.
1331 * @since 2.2
1332 */
1333 @SuppressWarnings("resource")
1334 public static boolean contentEqualsIgnoreEOL(final Reader reader1, final Reader reader2) throws UncheckedIOException {
1335 if (reader1 == reader2) {
1336 return true;
1337 }
1338 if (reader1 == null || reader2 == null) {
1339 return false;
1340 }
1341 return contentEqualsIgnoreEOL(toBufferedReader(reader1), toBufferedReader(reader2));
1342 }
1343
1344 /**
1345 * Copies bytes from an {@link InputStream} to an {@link OutputStream}.
1346 * <p>
1347 * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}.
1348 * </p>
1349 * <p>
1350 * Large streams (over 2GB) will return a bytes copied value of {@code -1} after the copy has completed since
1351 * the correct number of bytes cannot be returned as an int. For large streams use the
1352 * {@link #copyLarge(InputStream, OutputStream)} method.
1353 * </p>
1354 *
1355 * @param inputStream the {@link InputStream} to read.
1356 * @param outputStream the {@link OutputStream} to write.
1357 * @return the number of bytes copied, or -1 if greater than {@link Integer#MAX_VALUE}.
1358 * @throws NullPointerException if the InputStream is {@code null}.
1359 * @throws NullPointerException if the OutputStream is {@code null}.
1360 * @throws IOException if an I/O error occurs.
1361 * @since 1.1
1362 */
1363 public static int copy(final InputStream inputStream, final OutputStream outputStream) throws IOException {
1364 final long count = copyLarge(inputStream, outputStream);
1365 return count > Integer.MAX_VALUE ? EOF : (int) count;
1366 }
1367
1368 /**
1369 * Copies bytes from an {@link InputStream} to an {@link OutputStream} using an internal buffer of the
1370 * given size.
1371 * <p>
1372 * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}.
1373 * </p>
1374 *
1375 * @param inputStream the {@link InputStream} to read.
1376 * @param outputStream the {@link OutputStream} to write to.
1377 * @param bufferSize the bufferSize used to copy from the input to the output.
1378 * @return the number of bytes copied.
1379 * @throws NullPointerException if the InputStream is {@code null}.
1380 * @throws NullPointerException if the OutputStream is {@code null}.
1381 * @throws IOException if an I/O error occurs.
1382 * @since 2.5
1383 */
1384 public static long copy(final InputStream inputStream, final OutputStream outputStream, final int bufferSize) throws IOException {
1385 return copyLarge(inputStream, outputStream, byteArray(bufferSize));
1386 }
1387
1388 /**
1389 * Copies bytes from an {@link InputStream} to chars on a
1390 * {@link Writer} using the virtual machine's {@linkplain Charset#defaultCharset() default charset}.
1391 * <p>
1392 * This method buffers the input internally, so there is no need to use a
1393 * {@link BufferedInputStream}.
1394 * </p>
1395 * <p>
1396 * This method uses {@link InputStreamReader}.
1397 * </p>
1398 *
1399 * @param input the {@link InputStream} to read.
1400 * @param writer the {@link Writer} to write to.
1401 * @throws NullPointerException if the input or output is null.
1402 * @throws IOException if an I/O error occurs.
1403 * @since 1.1
1404 * @deprecated Use {@link #copy(InputStream, Writer, Charset)} instead.
1405 */
1406 @Deprecated
1407 public static void copy(final InputStream input, final Writer writer) throws IOException {
1408 copy(input, writer, Charset.defaultCharset());
1409 }
1410
1411 /**
1412 * Copies bytes from an {@link InputStream} to chars on a
1413 * {@link Writer} using the specified character encoding.
1414 * <p>
1415 * This method buffers the input internally, so there is no need to use a
1416 * {@link BufferedInputStream}.
1417 * </p>
1418 * <p>
1419 * This method uses {@link InputStreamReader}.
1420 * </p>
1421 *
1422 * @param input the {@link InputStream} to read.
1423 * @param writer the {@link Writer} to write to.
1424 * @param inputCharset the charset to use for the input stream, null means platform default.
1425 * @throws NullPointerException if the input or output is null.
1426 * @throws IOException if an I/O error occurs.
1427 * @since 2.3
1428 */
1429 public static void copy(final InputStream input, final Writer writer, final Charset inputCharset) throws IOException {
1430 copy(new InputStreamReader(input, Charsets.toCharset(inputCharset)), writer);
1431 }
1432
1433 /**
1434 * Copies bytes from an {@link InputStream} to chars on a
1435 * {@link Writer} using the specified character encoding.
1436 * <p>
1437 * This method buffers the input internally, so there is no need to use a
1438 * {@link BufferedInputStream}.
1439 * </p>
1440 * <p>
1441 * Character encoding names can be found at
1442 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
1443 * </p>
1444 * <p>
1445 * This method uses {@link InputStreamReader}.
1446 * </p>
1447 *
1448 * @param input the {@link InputStream} to read
1449 * @param writer the {@link Writer} to write to
1450 * @param inputCharsetName the name of the requested charset for the InputStream, null means platform default.
1451 * @throws NullPointerException if the input or output is null.
1452 * @throws IOException if an I/O error occurs.
1453 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
1454 * @since 1.1
1455 */
1456 public static void copy(final InputStream input, final Writer writer, final String inputCharsetName) throws IOException {
1457 copy(input, writer, Charsets.toCharset(inputCharsetName));
1458 }
1459
1460 /**
1461 * Copies bytes from a {@link ByteArrayOutputStream} to a {@link QueueInputStream}.
1462 * <p>
1463 * Unlike using JDK {@link PipedInputStream} and {@link PipedOutputStream} for this, this
1464 * solution works safely in a single thread environment.
1465 * </p>
1466 * <p>
1467 * Example usage:
1468 * </p>
1469 *
1470 * <pre>
1471 * ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
1472 * outputStream.writeBytes("hello world".getBytes(StandardCharsets.UTF_8));
1473 *
1474 * InputStream inputStream = IOUtils.copy(outputStream);
1475 * </pre>
1476 *
1477 * @param outputStream the {@link ByteArrayOutputStream} to read.
1478 * @return the {@link QueueInputStream} filled with the content of the outputStream.
1479 * @throws NullPointerException if the {@link ByteArrayOutputStream} is {@code null}.
1480 * @throws IOException if an I/O error occurs.
1481 * @since 2.12
1482 */
1483 @SuppressWarnings("resource") // streams are closed by the caller.
1484 public static QueueInputStream copy(final java.io.ByteArrayOutputStream outputStream) throws IOException {
1485 Objects.requireNonNull(outputStream, "outputStream");
1486 final QueueInputStream in = new QueueInputStream();
1487 outputStream.writeTo(in.newQueueOutputStream());
1488 return in;
1489 }
1490
1491 /**
1492 * Copies chars from a {@link Reader} to a {@link Appendable}.
1493 * <p>
1494 * This method buffers the input internally, so there is no need to use a
1495 * {@link BufferedReader}.
1496 * </p>
1497 * <p>
1498 * Large streams (over 2GB) will return a chars copied value of
1499 * {@code -1} after the copy has completed since the correct
1500 * number of chars cannot be returned as an int. For large streams
1501 * use the {@link #copyLarge(Reader, Writer)} method.
1502 * </p>
1503 *
1504 * @param reader the {@link Reader} to read.
1505 * @param output the {@link Appendable} to write to.
1506 * @return the number of characters copied, or -1 if > Integer.MAX_VALUE.
1507 * @throws NullPointerException if the input or output is null.
1508 * @throws IOException if an I/O error occurs.
1509 * @since 2.7
1510 */
1511 public static long copy(final Reader reader, final Appendable output) throws IOException {
1512 return copy(reader, output, CharBuffer.allocate(DEFAULT_BUFFER_SIZE));
1513 }
1514
1515 /**
1516 * Copies chars from a {@link Reader} to an {@link Appendable}.
1517 * <p>
1518 * This method uses the provided buffer, so there is no need to use a
1519 * {@link BufferedReader}.
1520 * </p>
1521 *
1522 * @param reader the {@link Reader} to read.
1523 * @param output the {@link Appendable} to write to.
1524 * @param buffer the buffer to be used for the copy.
1525 * @return the number of characters copied.
1526 * @throws NullPointerException if the input or output is null.
1527 * @throws IOException if an I/O error occurs.
1528 * @since 2.7
1529 */
1530 public static long copy(final Reader reader, final Appendable output, final CharBuffer buffer) throws IOException {
1531 long count = 0;
1532 int n;
1533 while (EOF != (n = reader.read(buffer))) {
1534 buffer.flip();
1535 output.append(buffer, 0, n);
1536 count += n;
1537 }
1538 return count;
1539 }
1540
1541 /**
1542 * Copies chars from a {@link Reader} to bytes on an {@link OutputStream} using the the virtual machine's {@linkplain Charset#defaultCharset() default
1543 * charset}, and calling flush.
1544 * <p>
1545 * This method buffers the input internally, so there is no need to use a {@link BufferedReader}.
1546 * </p>
1547 * <p>
1548 * Due to the implementation of OutputStreamWriter, this method performs a flush.
1549 * </p>
1550 * <p>
1551 * This method uses {@link OutputStreamWriter}.
1552 * </p>
1553 *
1554 * @param reader the {@link Reader} to read.
1555 * @param output the {@link OutputStream} to write to.
1556 * @throws NullPointerException if the input or output is null.
1557 * @throws IOException if an I/O error occurs.
1558 * @since 1.1
1559 * @deprecated Use {@link #copy(Reader, OutputStream, Charset)} instead
1560 */
1561 @Deprecated
1562 public static void copy(final Reader reader, final OutputStream output) throws IOException {
1563 copy(reader, output, Charset.defaultCharset());
1564 }
1565
1566 /**
1567 * Copies chars from a {@link Reader} to bytes on an {@link OutputStream} using the specified character encoding, and calling flush.
1568 * <p>
1569 * This method buffers the input internally, so there is no need to use a {@link BufferedReader}.
1570 * </p>
1571 * <p>
1572 * Due to the implementation of OutputStreamWriter, this method performs a flush.
1573 * </p>
1574 * <p>
1575 * This method uses {@link OutputStreamWriter}.
1576 * </p>
1577 *
1578 * @param reader the {@link Reader} to read.
1579 * @param output the {@link OutputStream} to write to.
1580 * @param outputCharset the charset to use for the OutputStream, null means platform default.
1581 * @throws NullPointerException if the input or output is null.
1582 * @throws IOException if an I/O error occurs.
1583 * @since 2.3
1584 */
1585 public static void copy(final Reader reader, final OutputStream output, final Charset outputCharset) throws IOException {
1586 final OutputStreamWriter writer = new OutputStreamWriter(output, Charsets.toCharset(outputCharset));
1587 copy(reader, writer);
1588 // XXX Unless anyone is planning on rewriting OutputStreamWriter,
1589 // we have to flush here.
1590 writer.flush();
1591 }
1592
1593 /**
1594 * Copies chars from a {@link Reader} to bytes on an {@link OutputStream} using the specified character encoding, and calling flush.
1595 * <p>
1596 * This method buffers the input internally, so there is no need to use a {@link BufferedReader}.
1597 * </p>
1598 * <p>
1599 * Character encoding names can be found at <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
1600 * </p>
1601 * <p>
1602 * Due to the implementation of OutputStreamWriter, this method performs a flush.
1603 * </p>
1604 * <p>
1605 * This method uses {@link OutputStreamWriter}.
1606 * </p>
1607 *
1608 * @param reader the {@link Reader} to read.
1609 * @param output the {@link OutputStream} to write to.
1610 * @param outputCharsetName the name of the requested charset for the OutputStream, null means platform default.
1611 * @throws NullPointerException if the input or output is null.
1612 * @throws IOException if an I/O error occurs.
1613 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
1614 * @since 1.1
1615 */
1616 public static void copy(final Reader reader, final OutputStream output, final String outputCharsetName) throws IOException {
1617 copy(reader, output, Charsets.toCharset(outputCharsetName));
1618 }
1619
1620 /**
1621 * Copies chars from a {@link Reader} to a {@link Writer}.
1622 * <p>
1623 * This method buffers the input internally, so there is no need to use a
1624 * {@link BufferedReader}.
1625 * </p>
1626 * <p>
1627 * Large streams (over 2GB) will return a chars copied value of
1628 * {@code -1} after the copy has completed since the correct
1629 * number of chars cannot be returned as an int. For large streams
1630 * use the {@link #copyLarge(Reader, Writer)} method.
1631 * </p>
1632 *
1633 * @param reader the {@link Reader} to read.
1634 * @param writer the {@link Writer} to write.
1635 * @return the number of characters copied, or -1 if > Integer.MAX_VALUE.
1636 * @throws NullPointerException if the input or output is null.
1637 * @throws IOException if an I/O error occurs.
1638 * @since 1.1
1639 */
1640 public static int copy(final Reader reader, final Writer writer) throws IOException {
1641 final long count = copyLarge(reader, writer);
1642 if (count > Integer.MAX_VALUE) {
1643 return EOF;
1644 }
1645 return (int) count;
1646 }
1647
1648 /**
1649 * Copies bytes from a {@link URL} to an {@link OutputStream}.
1650 * <p>
1651 * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}.
1652 * </p>
1653 * <p>
1654 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1655 * </p>
1656 *
1657 * @param url the {@link URL} to read.
1658 * @param file the {@link OutputStream} to write.
1659 * @return the number of bytes copied.
1660 * @throws NullPointerException if the URL is {@code null}.
1661 * @throws NullPointerException if the OutputStream is {@code null}.
1662 * @throws IOException if an I/O error occurs.
1663 * @since 2.9.0
1664 */
1665 public static long copy(final URL url, final File file) throws IOException {
1666 try (OutputStream outputStream = Files.newOutputStream(Objects.requireNonNull(file, "file").toPath())) {
1667 return copy(url, outputStream);
1668 }
1669 }
1670
1671 /**
1672 * Copies bytes from a {@link URL} to an {@link OutputStream}.
1673 * <p>
1674 * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}.
1675 * </p>
1676 * <p>
1677 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1678 * </p>
1679 *
1680 * @param url the {@link URL} to read.
1681 * @param outputStream the {@link OutputStream} to write.
1682 * @return the number of bytes copied.
1683 * @throws NullPointerException if the URL is {@code null}.
1684 * @throws NullPointerException if the OutputStream is {@code null}.
1685 * @throws IOException if an I/O error occurs.
1686 * @since 2.9.0
1687 */
1688 public static long copy(final URL url, final OutputStream outputStream) throws IOException {
1689 try (InputStream inputStream = Objects.requireNonNull(url, "url").openStream()) {
1690 return copyLarge(inputStream, outputStream);
1691 }
1692 }
1693
1694 /**
1695 * Copies bytes from a large (over 2GB) {@link InputStream} to an
1696 * {@link OutputStream}.
1697 * <p>
1698 * This method buffers the input internally, so there is no need to use a
1699 * {@link BufferedInputStream}.
1700 * </p>
1701 * <p>
1702 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1703 * </p>
1704 *
1705 * @param inputStream the {@link InputStream} to read.
1706 * @param outputStream the {@link OutputStream} to write.
1707 * @return the number of bytes copied.
1708 * @throws NullPointerException if the InputStream is {@code null}.
1709 * @throws NullPointerException if the OutputStream is {@code null}.
1710 * @throws IOException if an I/O error occurs.
1711 * @since 1.3
1712 */
1713 public static long copyLarge(final InputStream inputStream, final OutputStream outputStream)
1714 throws IOException {
1715 return copy(inputStream, outputStream, DEFAULT_BUFFER_SIZE);
1716 }
1717
1718 /**
1719 * Copies bytes from a large (over 2GB) {@link InputStream} to an
1720 * {@link OutputStream}.
1721 * <p>
1722 * This method uses the provided buffer, so there is no need to use a
1723 * {@link BufferedInputStream}.
1724 * </p>
1725 *
1726 * @param inputStream the {@link InputStream} to read.
1727 * @param outputStream the {@link OutputStream} to write.
1728 * @param buffer the buffer to use for the copy
1729 * @return the number of bytes copied.
1730 * @throws NullPointerException if the InputStream is {@code null}.
1731 * @throws NullPointerException if the OutputStream is {@code null}.
1732 * @throws IOException if an I/O error occurs.
1733 * @since 2.2
1734 */
1735 @SuppressWarnings("resource") // streams are closed by the caller.
1736 public static long copyLarge(final InputStream inputStream, final OutputStream outputStream, final byte[] buffer)
1737 throws IOException {
1738 Objects.requireNonNull(inputStream, "inputStream");
1739 Objects.requireNonNull(outputStream, "outputStream");
1740 long count = 0;
1741 int n;
1742 while (EOF != (n = inputStream.read(buffer))) {
1743 outputStream.write(buffer, 0, n);
1744 count += n;
1745 }
1746 return count;
1747 }
1748
1749 /**
1750 * Copies some or all bytes from a large (over 2GB) {@link InputStream} to an
1751 * {@link OutputStream}, optionally skipping input bytes.
1752 * <p>
1753 * This method buffers the input internally, so there is no need to use a
1754 * {@link BufferedInputStream}.
1755 * </p>
1756 * <p>
1757 * Note that the implementation uses {@link #skip(InputStream, long)}.
1758 * This means that the method may be considerably less efficient than using the actual skip implementation,
1759 * this is done to guarantee that the correct number of characters are skipped.
1760 * </p>
1761 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1762 *
1763 * @param input the {@link InputStream} to read.
1764 * @param output the {@link OutputStream} to write.
1765 * @param inputOffset number of bytes to skip from input before copying, these bytes are ignored.
1766 * @param length number of bytes to copy.
1767 * @return the number of bytes copied.
1768 * @throws NullPointerException if the input or output is null.
1769 * @throws IOException if an I/O error occurs.
1770 * @since 2.2
1771 */
1772 public static long copyLarge(final InputStream input, final OutputStream output, final long inputOffset, final long length) throws IOException {
1773 try (ScratchBytes scratch = ScratchBytes.get()) {
1774 return copyLarge(input, output, inputOffset, length, scratch.array());
1775 }
1776 }
1777
1778 /**
1779 * Copies some or all bytes from a large (over 2GB) {@link InputStream} to an
1780 * {@link OutputStream}, optionally skipping input bytes.
1781 * <p>
1782 * This method uses the provided buffer, so there is no need to use a
1783 * {@link BufferedInputStream}.
1784 * </p>
1785 * <p>
1786 * Note that the implementation uses {@link #skip(InputStream, long)}.
1787 * This means that the method may be considerably less efficient than using the actual skip implementation,
1788 * this is done to guarantee that the correct number of characters are skipped.
1789 * </p>
1790 *
1791 * @param input the {@link InputStream} to read.
1792 * @param output the {@link OutputStream} to write.
1793 * @param inputOffset number of bytes to skip from input before copying, these bytes are ignored.
1794 * @param length number of bytes to copy.
1795 * @param buffer the buffer to use for the copy.
1796 * @return the number of bytes copied.
1797 * @throws NullPointerException if the input or output is null.
1798 * @throws IOException if an I/O error occurs.
1799 * @since 2.2
1800 */
1801 public static long copyLarge(final InputStream input, final OutputStream output,
1802 final long inputOffset, final long length, final byte[] buffer) throws IOException {
1803 if (inputOffset > 0) {
1804 skipFully(input, inputOffset);
1805 }
1806 if (length == 0) {
1807 return 0;
1808 }
1809 final int bufferLength = buffer.length;
1810 int bytesToRead = bufferLength;
1811 if (length > 0 && length < bufferLength) {
1812 bytesToRead = (int) length;
1813 }
1814 int read;
1815 long totalRead = 0;
1816 while (bytesToRead > 0 && EOF != (read = input.read(buffer, 0, bytesToRead))) {
1817 output.write(buffer, 0, read);
1818 totalRead += read;
1819 if (length > 0) { // only adjust length if not reading to the end
1820 // Note the cast must work because buffer.length is an integer
1821 bytesToRead = (int) Math.min(length - totalRead, bufferLength);
1822 }
1823 }
1824 return totalRead;
1825 }
1826
1827 /**
1828 * Copies chars from a large (over 2GB) {@link Reader} to a {@link Writer}.
1829 * <p>
1830 * This method buffers the input internally, so there is no need to use a
1831 * {@link BufferedReader}.
1832 * </p>
1833 * <p>
1834 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1835 * </p>
1836 *
1837 * @param reader the {@link Reader} to source.
1838 * @param writer the {@link Writer} to target.
1839 * @return the number of characters copied.
1840 * @throws NullPointerException if the input or output is null.
1841 * @throws IOException if an I/O error occurs.
1842 * @since 1.3
1843 */
1844 public static long copyLarge(final Reader reader, final Writer writer) throws IOException {
1845 try (ScratchChars scratch = IOUtils.ScratchChars.get()) {
1846 return copyLarge(reader, writer, scratch.array());
1847 }
1848 }
1849
1850 /**
1851 * Copies chars from a large (over 2GB) {@link Reader} to a {@link Writer}.
1852 * <p>
1853 * This method uses the provided buffer, so there is no need to use a
1854 * {@link BufferedReader}.
1855 * </p>
1856 *
1857 * @param reader the {@link Reader} to source.
1858 * @param writer the {@link Writer} to target.
1859 * @param buffer the buffer to be used for the copy
1860 * @return the number of characters copied
1861 * @throws NullPointerException if the input or output is null
1862 * @throws IOException if an I/O error occurs
1863 * @since 2.2
1864 */
1865 public static long copyLarge(final Reader reader, final Writer writer, final char[] buffer) throws IOException {
1866 long count = 0;
1867 int n;
1868 while (EOF != (n = reader.read(buffer))) {
1869 writer.write(buffer, 0, n);
1870 count += n;
1871 }
1872 return count;
1873 }
1874
1875 /**
1876 * Copies some or all chars from a large (over 2GB) {@link InputStream} to an {@link OutputStream}, optionally skipping input chars.
1877 * <p>
1878 * This method buffers the input internally, so there is no need to use a {@link BufferedReader}.
1879 * </p>
1880 * <p>
1881 * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
1882 * </p>
1883 *
1884 * @param reader the {@link Reader} to read.
1885 * @param writer the {@link Writer} to write to.
1886 * @param inputOffset number of chars to skip from input before copying -ve values are ignored.
1887 * @param length number of chars to copy. -ve means all.
1888 * @return the number of chars copied.
1889 * @throws NullPointerException if the input or output is null.
1890 * @throws IOException if an I/O error occurs.
1891 * @since 2.2
1892 */
1893 public static long copyLarge(final Reader reader, final Writer writer, final long inputOffset, final long length) throws IOException {
1894 try (ScratchChars scratch = IOUtils.ScratchChars.get()) {
1895 return copyLarge(reader, writer, inputOffset, length, scratch.array());
1896 }
1897 }
1898
1899 /**
1900 * Copies some or all chars from a large (over 2GB) {@link InputStream} to an {@link OutputStream}, optionally skipping input chars.
1901 * <p>
1902 * This method uses the provided buffer, so there is no need to use a {@link BufferedReader}.
1903 * </p>
1904 *
1905 * @param reader the {@link Reader} to read.
1906 * @param writer the {@link Writer} to write to.
1907 * @param inputOffset number of chars to skip from input before copying -ve values are ignored.
1908 * @param length number of chars to copy. -ve means all.
1909 * @param buffer the buffer to be used for the copy.
1910 * @return the number of chars copied.
1911 * @throws NullPointerException if the input or output is null.
1912 * @throws IOException if an I/O error occurs.
1913 * @since 2.2
1914 */
1915 public static long copyLarge(final Reader reader, final Writer writer, final long inputOffset, final long length, final char[] buffer) throws IOException {
1916 if (inputOffset > 0) {
1917 skipFully(reader, inputOffset);
1918 }
1919 if (length == 0) {
1920 return 0;
1921 }
1922 int bytesToRead = buffer.length;
1923 if (length > 0 && length < buffer.length) {
1924 bytesToRead = (int) length;
1925 }
1926 int read;
1927 long totalRead = 0;
1928 while (bytesToRead > 0 && EOF != (read = reader.read(buffer, 0, bytesToRead))) {
1929 writer.write(buffer, 0, read);
1930 totalRead += read;
1931 if (length > 0) { // only adjust length if not reading to the end
1932 // Note the cast must work because buffer.length is an integer
1933 bytesToRead = (int) Math.min(length - totalRead, buffer.length);
1934 }
1935 }
1936 return totalRead;
1937 }
1938
1939 /**
1940 * Copies up to {@code size} bytes from the given {@link InputStream} into a new {@link UnsynchronizedByteArrayOutputStream}.
1941 *
1942 * @param input The {@link InputStream} to read; must not be {@code null}.
1943 * @param limit The maximum number of bytes to read; must be {@code >= 0}.
1944 * The actual bytes read are validated to equal {@code size}.
1945 * @param bufferSize The buffer size of the output stream; must be {@code > 0}.
1946 * @return a ByteArrayOutputStream containing the read bytes.
1947 */
1948 static UnsynchronizedByteArrayOutputStream copyToOutputStream(
1949 final InputStream input, final long limit, final int bufferSize) throws IOException {
1950 try (UnsynchronizedByteArrayOutputStream output = UnsynchronizedByteArrayOutputStream.builder()
1951 .setBufferSize(bufferSize)
1952 .get();
1953 InputStream boundedInput = BoundedInputStream.builder()
1954 .setMaxCount(limit)
1955 .setPropagateClose(false)
1956 .setInputStream(input)
1957 .get()) {
1958 output.write(boundedInput);
1959 return output;
1960 }
1961 }
1962
1963 /**
1964 * Returns the length of the given array in a null-safe manner.
1965 *
1966 * @param array an array or null.
1967 * @return the array length, or 0 if the given array is null.
1968 * @since 2.7
1969 */
1970 public static int length(final byte[] array) {
1971 return array == null ? 0 : array.length;
1972 }
1973
1974 /**
1975 * Returns the length of the given array in a null-safe manner.
1976 *
1977 * @param array an array or null.
1978 * @return the array length, or 0 if the given array is null.
1979 * @since 2.7
1980 */
1981 public static int length(final char[] array) {
1982 return array == null ? 0 : array.length;
1983 }
1984
1985 /**
1986 * Returns the length of the given CharSequence in a null-safe manner.
1987 *
1988 * @param csq a CharSequence or null.
1989 * @return the CharSequence length, or 0 if the given CharSequence is null.
1990 * @since 2.7
1991 */
1992 public static int length(final CharSequence csq) {
1993 return csq == null ? 0 : csq.length();
1994 }
1995
1996 /**
1997 * Returns the length of the given array in a null-safe manner.
1998 *
1999 * @param array an array or null.
2000 * @return the array length, or 0 if the given array is null.
2001 * @since 2.7
2002 */
2003 public static int length(final Object[] array) {
2004 return array == null ? 0 : array.length;
2005 }
2006
2007 /**
2008 * Returns an Iterator for the lines in an {@link InputStream}, using
2009 * the character encoding specified (or default encoding if null).
2010 * <p>
2011 * {@link LineIterator} holds a reference to the open
2012 * {@link InputStream} specified here. When you have finished with
2013 * the iterator you should close the stream to free internal resources.
2014 * This can be done by using a try-with-resources block, closing the stream directly, or by calling
2015 * {@link LineIterator#close()}.
2016 * </p>
2017 * <p>
2018 * The recommended usage pattern is:
2019 * </p>
2020 * <pre>
2021 * try {
2022 * LineIterator it = IOUtils.lineIterator(stream, charset);
2023 * while (it.hasNext()) {
2024 * String line = it.nextLine();
2025 * /// do something with line
2026 * }
2027 * } finally {
2028 * IOUtils.closeQuietly(stream);
2029 * }
2030 * </pre>
2031 *
2032 * @param input the {@link InputStream} to read, not null.
2033 * @param charset the charset to use, null means platform default.
2034 * @return an Iterator of the lines in the reader, never null.
2035 * @throws IllegalArgumentException if the input is null.
2036 * @since 2.3
2037 */
2038 public static LineIterator lineIterator(final InputStream input, final Charset charset) {
2039 return new LineIterator(new InputStreamReader(input, Charsets.toCharset(charset)));
2040 }
2041
2042 /**
2043 * Returns an Iterator for the lines in an {@link InputStream}, using
2044 * the character encoding specified (or default encoding if null).
2045 * <p>
2046 * {@link LineIterator} holds a reference to the open
2047 * {@link InputStream} specified here. When you have finished with
2048 * the iterator you should close the stream to free internal resources.
2049 * This can be done by using a try-with-resources block, closing the stream directly, or by calling
2050 * {@link LineIterator#close()}.
2051 * </p>
2052 * <p>
2053 * The recommended usage pattern is:
2054 * </p>
2055 * <pre>
2056 * try {
2057 * LineIterator it = IOUtils.lineIterator(stream, StandardCharsets.UTF_8.name());
2058 * while (it.hasNext()) {
2059 * String line = it.nextLine();
2060 * /// do something with line
2061 * }
2062 * } finally {
2063 * IOUtils.closeQuietly(stream);
2064 * }
2065 * </pre>
2066 *
2067 * @param input the {@link InputStream} to read, not null.
2068 * @param charsetName the encoding to use, null means platform default.
2069 * @return an Iterator of the lines in the reader, never null.
2070 * @throws IllegalArgumentException if the input is null.
2071 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
2072 * @since 1.2
2073 */
2074 public static LineIterator lineIterator(final InputStream input, final String charsetName) {
2075 return lineIterator(input, Charsets.toCharset(charsetName));
2076 }
2077
2078 /**
2079 * Returns an Iterator for the lines in a {@link Reader}.
2080 * <p>
2081 * {@link LineIterator} holds a reference to the open
2082 * {@link Reader} specified here. When you have finished with the
2083 * iterator you should close the reader to free internal resources.
2084 * This can be done by using a try-with-resources block, closing the reader directly, or by calling
2085 * {@link LineIterator#close()}.
2086 * </p>
2087 * <p>
2088 * The recommended usage pattern is:
2089 * </p>
2090 * <pre>
2091 * try {
2092 * LineIterator it = IOUtils.lineIterator(reader);
2093 * while (it.hasNext()) {
2094 * String line = it.nextLine();
2095 * /// do something with line
2096 * }
2097 * } finally {
2098 * IOUtils.closeQuietly(reader);
2099 * }
2100 * </pre>
2101 *
2102 * @param reader the {@link Reader} to read, not null.
2103 * @return an Iterator of the lines in the reader, never null.
2104 * @throws NullPointerException if the reader is null.
2105 * @since 1.2
2106 */
2107 public static LineIterator lineIterator(final Reader reader) {
2108 return new LineIterator(reader);
2109 }
2110
2111 /**
2112 * Reads bytes from an input stream.
2113 * <p>
2114 * This implementation guarantees that it will read as many bytes
2115 * as possible before giving up; this may not always be the case for
2116 * subclasses of {@link InputStream}.
2117 * </p>
2118 *
2119 * @param input where to read input from.
2120 * @param buffer destination.
2121 * @return actual length read; may be less than requested if EOF was reached.
2122 * @throws NullPointerException if {@code input} or {@code buffer} is null.
2123 * @throws IOException if a read error occurs.
2124 * @since 2.2
2125 */
2126 public static int read(final InputStream input, final byte[] buffer) throws IOException {
2127 return read(input, buffer, 0, buffer.length);
2128 }
2129
2130 /**
2131 * Reads bytes from an input stream.
2132 * <p>
2133 * This implementation guarantees that it will read as many bytes
2134 * as possible before giving up; this may not always be the case for
2135 * subclasses of {@link InputStream}.
2136 * </p>
2137 *
2138 * @param input where to read input.
2139 * @param buffer destination.
2140 * @param offset initial offset into buffer.
2141 * @param length length to read, must be >= 0.
2142 * @return actual length read; may be less than requested if EOF was reached.
2143 * @throws NullPointerException if {@code input} or {@code buffer} is null.
2144 * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if
2145 * {@code offset + length} is greater than {@code buffer.length}.
2146 * @throws IOException if a read error occurs.
2147 * @since 2.2
2148 */
2149 public static int read(final InputStream input, final byte[] buffer, final int offset, final int length)
2150 throws IOException {
2151 checkFromIndexSize(buffer, offset, length);
2152 int remaining = length;
2153 while (remaining > 0) {
2154 final int location = length - remaining;
2155 final int count = input.read(buffer, offset + location, remaining);
2156 if (EOF == count) {
2157 break;
2158 }
2159 remaining -= count;
2160 }
2161 return length - remaining;
2162 }
2163
2164 /**
2165 * Reads bytes from a ReadableByteChannel.
2166 * <p>
2167 * This implementation guarantees that it will read as many bytes
2168 * as possible before giving up; this may not always be the case for
2169 * subclasses of {@link ReadableByteChannel}.
2170 * </p>
2171 *
2172 * @param input the byte channel to read.
2173 * @param buffer byte buffer destination.
2174 * @return the actual length read; may be less than requested if EOF was reached.
2175 * @throws IOException if a read error occurs.
2176 * @since 2.5
2177 */
2178 public static int read(final ReadableByteChannel input, final ByteBuffer buffer) throws IOException {
2179 final int length = buffer.remaining();
2180 while (buffer.remaining() > 0) {
2181 final int count = input.read(buffer);
2182 if (EOF == count) { // EOF
2183 break;
2184 }
2185 }
2186 return length - buffer.remaining();
2187 }
2188
2189 /**
2190 * Reads characters from an input character stream.
2191 * <p>
2192 * This implementation guarantees that it will read as many characters
2193 * as possible before giving up; this may not always be the case for
2194 * subclasses of {@link Reader}.
2195 * </p>
2196 *
2197 * @param reader where to read input from.
2198 * @param buffer destination.
2199 * @return actual length read; may be less than requested if EOF was reached.
2200 * @throws IOException if a read error occurs.
2201 * @since 2.2
2202 */
2203 public static int read(final Reader reader, final char[] buffer) throws IOException {
2204 return read(reader, buffer, 0, buffer.length);
2205 }
2206
2207 /**
2208 * Reads characters from an input character stream.
2209 * <p>
2210 * This implementation guarantees that it will read as many characters
2211 * as possible before giving up; this may not always be the case for
2212 * subclasses of {@link Reader}.
2213 * </p>
2214 *
2215 * @param reader where to read input from.
2216 * @param buffer destination.
2217 * @param offset initial offset into buffer.
2218 * @param length length to read, must be >= 0.
2219 * @return actual length read; may be less than requested if EOF was reached.
2220 * @throws NullPointerException if {@code reader} or {@code buffer} is null.
2221 * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if
2222 * {@code offset + length} is greater than {@code buffer.length}.
2223 * @throws IOException if a read error occurs.
2224 * @since 2.2
2225 */
2226 public static int read(final Reader reader, final char[] buffer, final int offset, final int length)
2227 throws IOException {
2228 checkFromIndexSize(buffer, offset, length);
2229 int remaining = length;
2230 while (remaining > 0) {
2231 final int location = length - remaining;
2232 final int count = reader.read(buffer, offset + location, remaining);
2233 if (EOF == count) { // EOF
2234 break;
2235 }
2236 remaining -= count;
2237 }
2238 return length - remaining;
2239 }
2240
2241 /**
2242 * Reads the requested number of bytes or fail if there are not enough left.
2243 * <p>
2244 * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
2245 * not read as many bytes as requested (most likely because of reaching EOF).
2246 * </p>
2247 *
2248 * @param input where to read input from.
2249 * @param buffer destination.
2250 * @throws NullPointerException if {@code input} or {@code buffer} is null.
2251 * @throws EOFException if the number of bytes read was incorrect.
2252 * @throws IOException if there is a problem reading the file.
2253 * @since 2.2
2254 */
2255 public static void readFully(final InputStream input, final byte[] buffer) throws IOException {
2256 readFully(input, buffer, 0, buffer.length);
2257 }
2258
2259 /**
2260 * Reads the requested number of bytes or fail if there are not enough left.
2261 * <p>
2262 * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
2263 * not read as many bytes as requested (most likely because of reaching EOF).
2264 * </p>
2265 *
2266 * @param input where to read input from.
2267 * @param buffer destination.
2268 * @param offset initial offset into buffer.
2269 * @param length length to read, must be >= 0.
2270 * @throws NullPointerException if {@code input} or {@code buffer} is null.
2271 * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if
2272 * {@code offset + length} is greater than {@code buffer.length}.
2273 * @throws EOFException if the number of bytes read was incorrect.
2274 * @throws IOException if there is a problem reading the file.
2275 * @since 2.2
2276 */
2277 public static void readFully(final InputStream input, final byte[] buffer, final int offset, final int length)
2278 throws IOException {
2279 final int actual = read(input, buffer, offset, length);
2280 if (actual != length) {
2281 throw new EOFException("Length to read: " + length + " actual: " + actual);
2282 }
2283 }
2284
2285 /**
2286 * Reads the requested number of bytes or fail if there are not enough left.
2287 * <p>
2288 * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
2289 * not read as many bytes as requested (most likely because of reaching EOF).
2290 * </p>
2291 *
2292 * @param input where to read input from.
2293 * @param length length to read, must be >= 0.
2294 * @return the bytes read from input.
2295 * @throws IOException if there is a problem reading the file.
2296 * @throws IllegalArgumentException if length is negative.
2297 * @throws EOFException if the number of bytes read was incorrect.
2298 * @since 2.5
2299 * @deprecated Use {@link #toByteArray(InputStream, int)}.
2300 */
2301 @Deprecated
2302 public static byte[] readFully(final InputStream input, final int length) throws IOException {
2303 return toByteArray(input, length);
2304 }
2305
2306 /**
2307 * Reads the requested number of bytes or fail if there are not enough left.
2308 * <p>
2309 * This allows for the possibility that {@link ReadableByteChannel#read(ByteBuffer)} may
2310 * not read as many bytes as requested (most likely because of reaching EOF).
2311 * </p>
2312 *
2313 * @param input the byte channel to read.
2314 * @param buffer byte buffer destination.
2315 * @throws IOException if there is a problem reading the file.
2316 * @throws EOFException if the number of bytes read was incorrect.
2317 * @since 2.5
2318 */
2319 public static void readFully(final ReadableByteChannel input, final ByteBuffer buffer) throws IOException {
2320 final int expected = buffer.remaining();
2321 final int actual = read(input, buffer);
2322 if (actual != expected) {
2323 throw new EOFException("Length to read: " + expected + " actual: " + actual);
2324 }
2325 }
2326
2327 /**
2328 * Reads the requested number of characters or fail if there are not enough left.
2329 * <p>
2330 * This allows for the possibility that {@link Reader#read(char[], int, int)} may
2331 * not read as many characters as requested (most likely because of reaching EOF).
2332 * </p>
2333 *
2334 * @param reader where to read input from.
2335 * @param buffer destination.
2336 * @throws NullPointerException if {@code reader} or {@code buffer} is null.
2337 * @throws EOFException if the number of characters read was incorrect.
2338 * @throws IOException if there is a problem reading the file.
2339 * @since 2.2
2340 */
2341 public static void readFully(final Reader reader, final char[] buffer) throws IOException {
2342 readFully(reader, buffer, 0, buffer.length);
2343 }
2344
2345 /**
2346 * Reads the requested number of characters or fail if there are not enough left.
2347 * <p>
2348 * This allows for the possibility that {@link Reader#read(char[], int, int)} may
2349 * not read as many characters as requested (most likely because of reaching EOF).
2350 * </p>
2351 *
2352 * @param reader where to read input from.
2353 * @param buffer destination.
2354 * @param offset initial offset into buffer.
2355 * @param length length to read, must be >= 0.
2356 * @throws NullPointerException if {@code reader} or {@code buffer} is null.
2357 * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if
2358 * {@code offset + length} is greater than {@code buffer.length}.
2359 * @throws EOFException if the number of characters read was incorrect.
2360 * @throws IOException if there is a problem reading the file.
2361 * @since 2.2
2362 */
2363 public static void readFully(final Reader reader, final char[] buffer, final int offset, final int length)
2364 throws IOException {
2365 final int actual = read(reader, buffer, offset, length);
2366 if (actual != length) {
2367 throw new EOFException("Length to read: " + length + " actual: " + actual);
2368 }
2369 }
2370
2371 /**
2372 * Gets the contents of a {@link CharSequence} as a list of Strings, one entry per line.
2373 *
2374 * @param csq the {@link CharSequence} to read, not null.
2375 * @return the list of Strings, never null.
2376 * @throws UncheckedIOException if an I/O error occurs.
2377 * @since 2.18.0
2378 */
2379 public static List<String> readLines(final CharSequence csq) throws UncheckedIOException {
2380 try (CharSequenceReader reader = new CharSequenceReader(csq)) {
2381 return readLines(reader);
2382 }
2383 }
2384
2385 /**
2386 * Gets the contents of an {@link InputStream} as a list of Strings,
2387 * one entry per line, using the virtual machine's {@linkplain Charset#defaultCharset() default charset}.
2388 * <p>
2389 * This method buffers the input internally, so there is no need to use a
2390 * {@link BufferedInputStream}.
2391 * </p>
2392 *
2393 * @param input the {@link InputStream} to read, not null.
2394 * @return the list of Strings, never null.
2395 * @throws NullPointerException if the input is null.
2396 * @throws UncheckedIOException if an I/O error occurs.
2397 * @since 1.1
2398 * @deprecated Use {@link #readLines(InputStream, Charset)} instead
2399 */
2400 @Deprecated
2401 public static List<String> readLines(final InputStream input) throws UncheckedIOException {
2402 return readLines(input, Charset.defaultCharset());
2403 }
2404
2405 /**
2406 * Gets the contents of an {@link InputStream} as a list of Strings,
2407 * one entry per line, using the specified character encoding.
2408 * <p>
2409 * This method buffers the input internally, so there is no need to use a
2410 * {@link BufferedInputStream}.
2411 * </p>
2412 *
2413 * @param input the {@link InputStream} to read, not null.
2414 * @param charset the charset to use, null means platform default.
2415 * @return the list of Strings, never null.
2416 * @throws NullPointerException if the input is null.
2417 * @throws UncheckedIOException if an I/O error occurs.
2418 * @since 2.3
2419 */
2420 public static List<String> readLines(final InputStream input, final Charset charset) throws UncheckedIOException {
2421 return readLines(new InputStreamReader(input, Charsets.toCharset(charset)));
2422 }
2423
2424 /**
2425 * Gets the contents of an {@link InputStream} as a list of Strings,
2426 * one entry per line, using the specified character encoding.
2427 * <p>
2428 * Character encoding names can be found at
2429 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
2430 * </p>
2431 * <p>
2432 * This method buffers the input internally, so there is no need to use a
2433 * {@link BufferedInputStream}.
2434 * </p>
2435 *
2436 * @param input the {@link InputStream} to read, not null.
2437 * @param charsetName the name of the requested charset, null means platform default.
2438 * @return the list of Strings, never null.
2439 * @throws NullPointerException if the input is null.
2440 * @throws UncheckedIOException if an I/O error occurs.
2441 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
2442 * @since 1.1
2443 */
2444 public static List<String> readLines(final InputStream input, final String charsetName) throws UncheckedIOException {
2445 return readLines(input, Charsets.toCharset(charsetName));
2446 }
2447
2448 /**
2449 * Gets the contents of a {@link Reader} as a list of Strings,
2450 * one entry per line.
2451 * <p>
2452 * This method buffers the input internally, so there is no need to use a
2453 * {@link BufferedReader}.
2454 * </p>
2455 *
2456 * @param reader the {@link Reader} to read, not null.
2457 * @return the list of Strings, never null.
2458 * @throws NullPointerException if the input is null.
2459 * @throws UncheckedIOException if an I/O error occurs.
2460 * @since 1.1
2461 */
2462 @SuppressWarnings("resource") // reader wraps input and is the responsibility of the caller.
2463 public static List<String> readLines(final Reader reader) throws UncheckedIOException {
2464 return toBufferedReader(reader).lines().collect(Collectors.toList());
2465 }
2466
2467 /**
2468 * Gets the contents of a resource as a byte array.
2469 * <p>
2470 * Delegates to {@link #resourceToByteArray(String, ClassLoader) resourceToByteArray(String, null)}.
2471 * </p>
2472 *
2473 * @param name The resource name.
2474 * @return the requested byte array.
2475 * @throws IOException if an I/O error occurs or the resource is not found.
2476 * @see #resourceToByteArray(String, ClassLoader)
2477 * @since 2.6
2478 */
2479 public static byte[] resourceToByteArray(final String name) throws IOException {
2480 return resourceToByteArray(name, null);
2481 }
2482
2483 /**
2484 * Gets the contents of a resource as a byte array.
2485 * <p>
2486 * Delegates to {@link #resourceToURL(String, ClassLoader)}.
2487 * </p>
2488 *
2489 * @param name The resource name.
2490 * @param classLoader the class loader that the resolution of the resource is delegated to.
2491 * @return the requested byte array.
2492 * @throws IOException if an I/O error occurs or the resource is not found.
2493 * @see #resourceToURL(String, ClassLoader)
2494 * @since 2.6
2495 */
2496 public static byte[] resourceToByteArray(final String name, final ClassLoader classLoader) throws IOException {
2497 return toByteArray(resourceToURL(name, classLoader));
2498 }
2499
2500 /**
2501 * Gets the contents of a resource as a String using the specified character encoding.
2502 * <p>
2503 * Delegates to {@link #resourceToString(String, Charset, ClassLoader) resourceToString(String, Charset, null)}.
2504 * </p>
2505 *
2506 * @param name The resource name.
2507 * @param charset the charset to use, null means platform default.
2508 * @return the requested String.
2509 * @throws IOException if an I/O error occurs or the resource is not found.
2510 * @see #resourceToString(String, Charset, ClassLoader)
2511 * @since 2.6
2512 */
2513 public static String resourceToString(final String name, final Charset charset) throws IOException {
2514 return resourceToString(name, charset, null);
2515 }
2516
2517 /**
2518 * Gets the contents of a resource as a String using the specified character encoding.
2519 * <p>
2520 * Delegates to {@link #resourceToURL(String, ClassLoader)}.
2521 * </p>
2522 *
2523 * @param name The resource name.
2524 * @param charset the Charset to use, null means platform default.
2525 * @param classLoader the class loader that the resolution of the resource is delegated to.
2526 * @return the requested String.
2527 * @throws IOException if an I/O error occurs.
2528 * @see #resourceToURL(String, ClassLoader)
2529 * @since 2.6
2530 */
2531 public static String resourceToString(final String name, final Charset charset, final ClassLoader classLoader) throws IOException {
2532 return toString(resourceToURL(name, classLoader), charset);
2533 }
2534
2535 /**
2536 * Gets a URL pointing to the given resource.
2537 * <p>
2538 * Delegates to {@link #resourceToURL(String, ClassLoader) resourceToURL(String, null)}.
2539 * </p>
2540 *
2541 * @param name The resource name.
2542 * @return A URL object for reading the resource.
2543 * @throws IOException if the resource is not found.
2544 * @since 2.6
2545 */
2546 public static URL resourceToURL(final String name) throws IOException {
2547 return resourceToURL(name, null);
2548 }
2549
2550 /**
2551 * Gets a URL pointing to the given resource.
2552 * <p>
2553 * If the {@code classLoader} is not null, call {@link ClassLoader#getResource(String)}, otherwise call
2554 * {@link Class#getResource(String) IOUtils.class.getResource(name)}.
2555 * </p>
2556 *
2557 * @param name The resource name.
2558 * @param classLoader Delegate to this class loader if not null.
2559 * @return A URL object for reading the resource.
2560 * @throws IOException if the resource is not found.
2561 * @since 2.6
2562 */
2563 public static URL resourceToURL(final String name, final ClassLoader classLoader) throws IOException {
2564 // What about the thread context class loader?
2565 // What about the system class loader?
2566 final URL resource = classLoader == null ? IOUtils.class.getResource(name) : classLoader.getResource(name);
2567 if (resource == null) {
2568 throw new IOException("Resource not found: " + name);
2569 }
2570 return resource;
2571 }
2572
2573 /**
2574 * Skips bytes from an input byte stream.
2575 * <p>
2576 * This implementation guarantees that it will read as many bytes as possible before giving up; this may not always be the case for skip() implementations
2577 * in subclasses of {@link InputStream}.
2578 * </p>
2579 * <p>
2580 * Note that the implementation uses {@link InputStream#read(byte[], int, int)} rather than delegating to {@link InputStream#skip(long)}. This means that
2581 * the method may be considerably less efficient than using the actual skip implementation, this is done to guarantee that the correct number of bytes are
2582 * skipped.
2583 * </p>
2584 *
2585 * @param input byte stream to skip.
2586 * @param skip number of bytes to skip.
2587 * @return number of bytes actually skipped.
2588 * @throws IOException if there is a problem reading the file.
2589 * @throws IllegalArgumentException if toSkip is negative.
2590 * @see InputStream#skip(long)
2591 * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a>
2592 * @since 2.0
2593 */
2594 public static long skip(final InputStream input, final long skip) throws IOException {
2595 try (ScratchBytes scratch = ScratchBytes.get()) {
2596 return skip(input, skip, scratch::array);
2597 }
2598 }
2599
2600 /**
2601 * Skips bytes from an input byte stream.
2602 * <p>
2603 * Intended for special cases when customization of the temporary buffer is needed because, for example, a nested input stream has requirements for the
2604 * bytes read. For example, when using {@link InflaterInputStream}s from multiple threads.
2605 * </p>
2606 * <p>
2607 * This implementation guarantees that it will read as many bytes as possible before giving up; this may not always be the case for skip() implementations
2608 * in subclasses of {@link InputStream}.
2609 * </p>
2610 * <p>
2611 * Note that the implementation uses {@link InputStream#read(byte[], int, int)} rather than delegating to {@link InputStream#skip(long)}. This means that
2612 * the method may be considerably less efficient than using the actual skip implementation, this is done to guarantee that the correct number of bytes are
2613 * skipped.
2614 * </p>
2615 *
2616 * @param input byte stream to skip.
2617 * @param skip number of bytes to skip.
2618 * @param skipBufferSupplier Supplies the buffer to use for reading.
2619 * @return number of bytes actually skipped.
2620 * @throws IOException if there is a problem reading the file.
2621 * @throws IllegalArgumentException if toSkip is negative.
2622 * @see InputStream#skip(long)
2623 * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a>
2624 * @since 2.14.0
2625 */
2626 public static long skip(final InputStream input, final long skip, final Supplier<byte[]> skipBufferSupplier) throws IOException {
2627 if (skip < 0) {
2628 throw new IllegalArgumentException("Skip count must be non-negative, actual: " + skip);
2629 }
2630 //
2631 // No need to synchronize access to SCRATCH_BYTE_BUFFER_WO: We don't care if the buffer is written multiple
2632 // times or in parallel since the data is ignored. We reuse the same buffer, if the buffer size were variable or read-write,
2633 // we would need to synch or use a thread local to ensure some other thread safety.
2634 //
2635 long remain = skip;
2636 while (remain > 0) {
2637 final byte[] skipBuffer = skipBufferSupplier.get();
2638 // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip()
2639 final long n = input.read(skipBuffer, 0, (int) Math.min(remain, skipBuffer.length));
2640 if (n < 0) { // EOF
2641 break;
2642 }
2643 remain -= n;
2644 }
2645 return skip - remain;
2646 }
2647
2648 /**
2649 * Skips bytes from a ReadableByteChannel.
2650 * This implementation guarantees that it will read as many bytes
2651 * as possible before giving up.
2652 *
2653 * @param input ReadableByteChannel to skip.
2654 * @param toSkip number of bytes to skip.
2655 * @return number of bytes actually skipped.
2656 * @throws IOException if there is a problem reading the ReadableByteChannel.
2657 * @throws IllegalArgumentException if toSkip is negative.
2658 * @since 2.5
2659 */
2660 public static long skip(final ReadableByteChannel input, final long toSkip) throws IOException {
2661 if (toSkip < 0) {
2662 throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
2663 }
2664 final ByteBuffer skipByteBuffer = ByteBuffer.allocate((int) Math.min(toSkip, DEFAULT_BUFFER_SIZE));
2665 long remain = toSkip;
2666 while (remain > 0) {
2667 skipByteBuffer.position(0);
2668 skipByteBuffer.limit((int) Math.min(remain, DEFAULT_BUFFER_SIZE));
2669 final int n = input.read(skipByteBuffer);
2670 if (n == EOF) {
2671 break;
2672 }
2673 remain -= n;
2674 }
2675 return toSkip - remain;
2676 }
2677
2678 /**
2679 * Skips characters from an input character stream.
2680 * This implementation guarantees that it will read as many characters
2681 * as possible before giving up; this may not always be the case for
2682 * skip() implementations in subclasses of {@link Reader}.
2683 * <p>
2684 * Note that the implementation uses {@link Reader#read(char[], int, int)} rather
2685 * than delegating to {@link Reader#skip(long)}.
2686 * This means that the method may be considerably less efficient than using the actual skip implementation,
2687 * this is done to guarantee that the correct number of characters are skipped.
2688 * </p>
2689 *
2690 * @param reader character stream to skip.
2691 * @param toSkip number of characters to skip.
2692 * @return number of characters actually skipped.
2693 * @throws IOException if there is a problem reading the file.
2694 * @throws IllegalArgumentException if toSkip is negative.
2695 * @see Reader#skip(long)
2696 * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a>
2697 * @since 2.0
2698 */
2699 public static long skip(final Reader reader, final long toSkip) throws IOException {
2700 if (toSkip < 0) {
2701 throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
2702 }
2703 long remain = toSkip;
2704 try (ScratchChars scratch = IOUtils.ScratchChars.get()) {
2705 final char[] chars = scratch.array();
2706 while (remain > 0) {
2707 // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip()
2708 final long n = reader.read(chars, 0, (int) Math.min(remain, chars.length));
2709 if (n < 0) { // EOF
2710 break;
2711 }
2712 remain -= n;
2713 }
2714 }
2715 return toSkip - remain;
2716 }
2717
2718 /**
2719 * Skips the requested number of bytes or fail if there are not enough left.
2720 * <p>
2721 * This allows for the possibility that {@link InputStream#skip(long)} may
2722 * not skip as many bytes as requested (most likely because of reaching EOF).
2723 * </p>
2724 * <p>
2725 * Note that the implementation uses {@link #skip(InputStream, long)}.
2726 * This means that the method may be considerably less efficient than using the actual skip implementation,
2727 * this is done to guarantee that the correct number of characters are skipped.
2728 * </p>
2729 *
2730 * @param input stream to skip.
2731 * @param toSkip the number of bytes to skip.
2732 * @throws IOException if there is a problem reading the file.
2733 * @throws IllegalArgumentException if toSkip is negative.
2734 * @throws EOFException if the number of bytes skipped was incorrect.
2735 * @see InputStream#skip(long)
2736 * @since 2.0
2737 */
2738 public static void skipFully(final InputStream input, final long toSkip) throws IOException {
2739 final long skipped = skip(input, toSkip);
2740 if (skipped != toSkip) {
2741 throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped);
2742 }
2743 }
2744
2745 /**
2746 * Skips the requested number of bytes or fail if there are not enough left.
2747 * <p>
2748 * Intended for special cases when customization of the temporary buffer is needed because, for example, a nested input stream has requirements for the
2749 * bytes read. For example, when using {@link InflaterInputStream}s from multiple threads.
2750 * </p>
2751 * <p>
2752 * This allows for the possibility that {@link InputStream#skip(long)} may not skip as many bytes as requested (most likely because of reaching EOF).
2753 * </p>
2754 * <p>
2755 * Note that the implementation uses {@link #skip(InputStream, long)}. This means that the method may be considerably less efficient than using the actual
2756 * skip implementation, this is done to guarantee that the correct number of characters are skipped.
2757 * </p>
2758 *
2759 * @param input stream to skip.
2760 * @param toSkip the number of bytes to skip.
2761 * @param skipBufferSupplier Supplies the buffer to use for reading.
2762 * @throws IOException if there is a problem reading the file.
2763 * @throws IllegalArgumentException if toSkip is negative.
2764 * @throws EOFException if the number of bytes skipped was incorrect.
2765 * @see InputStream#skip(long)
2766 * @since 2.14.0
2767 */
2768 public static void skipFully(final InputStream input, final long toSkip, final Supplier<byte[]> skipBufferSupplier) throws IOException {
2769 if (toSkip < 0) {
2770 throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip);
2771 }
2772 final long skipped = skip(input, toSkip, skipBufferSupplier);
2773 if (skipped != toSkip) {
2774 throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped);
2775 }
2776 }
2777
2778 /**
2779 * Skips the requested number of bytes or fail if there are not enough left.
2780 *
2781 * @param input ReadableByteChannel to skip.
2782 * @param toSkip the number of bytes to skip.
2783 * @throws IOException if there is a problem reading the ReadableByteChannel.
2784 * @throws IllegalArgumentException if toSkip is negative.
2785 * @throws EOFException if the number of bytes skipped was incorrect.
2786 * @since 2.5
2787 */
2788 public static void skipFully(final ReadableByteChannel input, final long toSkip) throws IOException {
2789 if (toSkip < 0) {
2790 throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip);
2791 }
2792 final long skipped = skip(input, toSkip);
2793 if (skipped != toSkip) {
2794 throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped);
2795 }
2796 }
2797
2798 /**
2799 * Skips the requested number of characters or fail if there are not enough left.
2800 * <p>
2801 * This allows for the possibility that {@link Reader#skip(long)} may
2802 * not skip as many characters as requested (most likely because of reaching EOF).
2803 * </p>
2804 * <p>
2805 * Note that the implementation uses {@link #skip(Reader, long)}.
2806 * This means that the method may be considerably less efficient than using the actual skip implementation,
2807 * this is done to guarantee that the correct number of characters are skipped.
2808 * </p>
2809 *
2810 * @param reader stream to skip.
2811 * @param toSkip the number of characters to skip.
2812 * @throws IOException if there is a problem reading the file.
2813 * @throws IllegalArgumentException if toSkip is negative.
2814 * @throws EOFException if the number of characters skipped was incorrect.
2815 * @see Reader#skip(long)
2816 * @since 2.0
2817 */
2818 public static void skipFully(final Reader reader, final long toSkip) throws IOException {
2819 final long skipped = skip(reader, toSkip);
2820 if (skipped != toSkip) {
2821 throw new EOFException("Chars to skip: " + toSkip + " actual: " + skipped);
2822 }
2823 }
2824
2825 /**
2826 * Fetches entire contents of an {@link InputStream} and represent same data as result InputStream.
2827 * <p>
2828 * This method is useful where,
2829 * </p>
2830 * <ul>
2831 * <li>Source InputStream is slow.</li>
2832 * <li>It has network resources associated, so we cannot keep it open for long time.</li>
2833 * <li>It has network timeout associated.</li>
2834 * </ul>
2835 * <p>
2836 * It can be used in favor of {@link #toByteArray(InputStream)}, since it avoids unnecessary allocation and copy of byte[].<br>
2837 * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}.
2838 * </p>
2839 *
2840 * @param input Stream to be fully buffered.
2841 * @return A fully buffered stream.
2842 * @throws IOException if an I/O error occurs.
2843 * @since 2.0
2844 */
2845 public static InputStream toBufferedInputStream(final InputStream input) throws IOException {
2846 return ByteArrayOutputStream.toBufferedInputStream(input);
2847 }
2848
2849 /**
2850 * Fetches entire contents of an {@link InputStream} and represent same data as result InputStream.
2851 * <p>
2852 * This method is useful where,
2853 * </p>
2854 * <ul>
2855 * <li>Source InputStream is slow.</li>
2856 * <li>It has network resources associated, so we cannot keep it open for long time.</li>
2857 * <li>It has network timeout associated.</li>
2858 * </ul>
2859 * <p>
2860 * It can be used in favor of {@link #toByteArray(InputStream)}, since it avoids unnecessary allocation and copy of byte[].<br>
2861 * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}.
2862 * </p>
2863 *
2864 * @param input Stream to be fully buffered.
2865 * @param size the initial buffer size.
2866 * @return A fully buffered stream.
2867 * @throws IOException if an I/O error occurs.
2868 * @since 2.5
2869 */
2870 public static InputStream toBufferedInputStream(final InputStream input, final int size) throws IOException {
2871 return ByteArrayOutputStream.toBufferedInputStream(input, size);
2872 }
2873
2874 /**
2875 * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given
2876 * reader.
2877 *
2878 * @param reader the reader to wrap or return (not null).
2879 * @return the given reader or a new {@link BufferedReader} for the given reader.
2880 * @throws NullPointerException if the input parameter is null.
2881 * @see #buffer(Reader)
2882 * @since 2.2
2883 */
2884 public static BufferedReader toBufferedReader(final Reader reader) {
2885 return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader);
2886 }
2887
2888 /**
2889 * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given
2890 * reader.
2891 *
2892 * @param reader the reader to wrap or return (not null).
2893 * @param size the buffer size, if a new BufferedReader is created.
2894 * @return the given reader or a new {@link BufferedReader} for the given reader.
2895 * @throws NullPointerException if the input parameter is null.
2896 * @see #buffer(Reader)
2897 * @since 2.5
2898 */
2899 public static BufferedReader toBufferedReader(final Reader reader, final int size) {
2900 return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader, size);
2901 }
2902
2903 /**
2904 * Reads all the bytes from an input stream in a byte array.
2905 *
2906 * <p>The memory used by this method is <strong>proportional</strong> to the number
2907 * of bytes read, which is only limited by {@link Integer#MAX_VALUE}. Only streams
2908 * which fit into a single byte array with roughly 2 GiB limit can be processed
2909 * with this method.</p>
2910 *
2911 * @param inputStream The {@link InputStream} to read; must not be {@code null}.
2912 * @return A new byte array.
2913 * @throws IOException If an I/O error occurs while reading or if the maximum array size is exceeded.
2914 * @throws NullPointerException If {@code inputStream} is {@code null}.
2915 */
2916 public static byte[] toByteArray(final InputStream inputStream) throws IOException {
2917 // Using SOFT_MAX_ARRAY_LENGTH guarantees that size() will not overflow
2918 final UnsynchronizedByteArrayOutputStream output = copyToOutputStream(inputStream, SOFT_MAX_ARRAY_LENGTH + 1, DEFAULT_BUFFER_SIZE);
2919 if (output.size() > SOFT_MAX_ARRAY_LENGTH) {
2920 throw new IOException(String.format("Cannot read more than %,d into a byte array", SOFT_MAX_ARRAY_LENGTH));
2921 }
2922 return output.toByteArray();
2923 }
2924
2925 /**
2926 * Reads exactly {@code size} bytes from the given {@link InputStream} into a new {@code byte[]}.
2927 *
2928 * <p>This variant always allocates the whole requested array size,
2929 * for a dynamic growing variant use {@link #toByteArray(InputStream, int, int)},
2930 * which enforces stricter memory usage constraints.</p>
2931 *
2932 * @param input the {@link InputStream} to read; must not be {@code null}.
2933 * @param size the exact number of bytes to read; must be {@code >= 0}.
2934 * @return a new byte array of length {@code size}.
2935 * @throws IllegalArgumentException if {@code size} is negative.
2936 * @throws EOFException if the stream ends before {@code size} bytes are read.
2937 * @throws IOException if an I/O error occurs while reading.
2938 * @throws NullPointerException if {@code input} is {@code null}.
2939 * @since 2.1
2940 */
2941 public static byte[] toByteArray(final InputStream input, final int size) throws IOException {
2942 return toByteArray(Objects.requireNonNull(input, "input")::read, size);
2943 }
2944
2945 /**
2946 * Reads exactly {@code size} bytes from the given {@link InputStream} into a new {@code byte[]}.
2947 *
2948 * <p>The memory used by this method is <strong>proportional</strong> to the number
2949 * of bytes read and limited by the specified {@code size}. This makes it suitable for
2950 * processing large input streams, provided that <strong>sufficient</strong> heap space is
2951 * available.</p>
2952 *
2953 * <p>This method processes the input stream in successive chunks of up to
2954 * {@code chunkSize} bytes.</p>
2955 *
2956 * @param input the {@link InputStream} to read; must not be {@code null}.
2957 * @param size the exact number of bytes to read; must be {@code >= 0}.
2958 * The actual bytes read are validated to equal {@code size}.
2959 * @param chunkSize The chunk size for incremental reading; must be {@code > 0}.
2960 * @return a new byte array of length {@code size}.
2961 * @throws IllegalArgumentException if {@code size} is negative or {@code chunkSize <= 0}.
2962 * @throws EOFException if the stream ends before {@code size} bytes are read.
2963 * @throws IOException if an I/O error occurs while reading.
2964 * @throws NullPointerException if {@code input} is {@code null}.
2965 * @since 2.21.0
2966 */
2967 public static byte[] toByteArray(final InputStream input, final int size, final int chunkSize) throws IOException {
2968 Objects.requireNonNull(input, "input");
2969 if (chunkSize <= 0) {
2970 throw new IllegalArgumentException(String.format("chunkSize <= 0, chunkSize = %,d", chunkSize));
2971 }
2972 if (size <= chunkSize) {
2973 // throws if size < 0
2974 return toByteArray(input::read, size);
2975 }
2976 final UnsynchronizedByteArrayOutputStream output = copyToOutputStream(input, size, chunkSize);
2977 final int outSize = output.size();
2978 if (outSize != size) {
2979 throw new EOFException(String.format("Expected read size: %,d, actual: %,d", size, outSize));
2980 }
2981 return output.toByteArray();
2982 }
2983
2984 /**
2985 * Reads exactly {@code size} bytes from the given {@link InputStream} into a new {@code byte[]}.
2986 *
2987 * <p>This variant always allocates the whole requested array size,
2988 * for a dynamic growing variant use {@link #toByteArray(InputStream, int, int)},
2989 * which enforces stricter memory usage constraints.</p>
2990 *
2991 * @param input the {@link InputStream} to read; must not be {@code null}.
2992 * @param size the exact number of bytes to read; must be {@code >= 0} and {@code <= Integer.MAX_VALUE}.
2993 * @return a new byte array of length {@code size}.
2994 * @throws IllegalArgumentException if {@code size} is negative or does not fit into an int.
2995 * @throws EOFException if the stream ends before {@code size} bytes are read.
2996 * @throws IOException if an I/O error occurs while reading.
2997 * @throws NullPointerException if {@code input} is {@code null}.
2998 * @see #toByteArray(InputStream, int, int)
2999 * @since 2.1
3000 */
3001 public static byte[] toByteArray(final InputStream input, final long size) throws IOException {
3002 if (size > Integer.MAX_VALUE) {
3003 throw new IllegalArgumentException(String.format("size > Integer.MAX_VALUE, size = %,d", size));
3004 }
3005 return toByteArray(input, (int) size);
3006 }
3007
3008 /**
3009 * Gets the contents of an input as a {@code byte[]}.
3010 *
3011 * @param input the input to read, not null.
3012 * @param size the size of the input to read, where 0 < {@code size} <= length of input.
3013 * @return byte [] of length {@code size}.
3014 * @throws EOFException if the end of the input is reached before reading {@code size} bytes.
3015 * @throws IOException if an I/O error occurs or input length is smaller than parameter {@code size}.
3016 * @throws IllegalArgumentException if {@code size} is less than zero.
3017 */
3018 static byte[] toByteArray(final IOTriFunction<byte[], Integer, Integer, Integer> input, final int size) throws IOException {
3019 if (size < 0) {
3020 throw new IllegalArgumentException(String.format("size < 0, size = %,d", size));
3021 }
3022 if (size == 0) {
3023 return EMPTY_BYTE_ARRAY;
3024 }
3025 final byte[] data = byteArray(size);
3026 int offset = 0;
3027 int read;
3028 while (offset < size && (read = input.apply(data, offset, size - offset)) != EOF) {
3029 offset += read;
3030 }
3031 if (offset != size) {
3032 throw new EOFException(String.format("Expected read size: %,d, actual: %,d", size, offset));
3033 }
3034 return data;
3035 }
3036
3037 /**
3038 * Gets the contents of a {@link Reader} as a {@code byte[]}
3039 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}.
3040 * <p>
3041 * This method buffers the input internally, so there is no need to use a
3042 * {@link BufferedReader}.
3043 * </p>
3044 *
3045 * @param reader the {@link Reader} to read.
3046 * @return the requested byte array.
3047 * @throws NullPointerException if the input is null.
3048 * @throws IOException if an I/O error occurs.
3049 * @deprecated Use {@link #toByteArray(Reader, Charset)} instead.
3050 */
3051 @Deprecated
3052 public static byte[] toByteArray(final Reader reader) throws IOException {
3053 return toByteArray(reader, Charset.defaultCharset());
3054 }
3055
3056 /**
3057 * Gets the contents of a {@link Reader} as a {@code byte[]}
3058 * using the specified character encoding.
3059 * <p>
3060 * This method buffers the input internally, so there is no need to use a
3061 * {@link BufferedReader}.
3062 * </p>
3063 *
3064 * @param reader the {@link Reader} to read.
3065 * @param charset the charset to use, null means platform default.
3066 * @return the requested byte array.
3067 * @throws NullPointerException if the input is null.
3068 * @throws IOException if an I/O error occurs.
3069 * @since 2.3
3070 */
3071 public static byte[] toByteArray(final Reader reader, final Charset charset) throws IOException {
3072 try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
3073 copy(reader, output, charset);
3074 return output.toByteArray();
3075 }
3076 }
3077
3078 /**
3079 * Gets the contents of a {@link Reader} as a {@code byte[]}
3080 * using the specified character encoding.
3081 * <p>
3082 * Character encoding names can be found at
3083 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
3084 * </p>
3085 * <p>
3086 * This method buffers the input internally, so there is no need to use a
3087 * {@link BufferedReader}.
3088 * </p>
3089 *
3090 * @param reader the {@link Reader} to read.
3091 * @param charsetName the name of the requested charset, null means platform default.
3092 * @return the requested byte array.
3093 * @throws NullPointerException if the input is null.
3094 * @throws IOException if an I/O error occurs.
3095 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
3096 * @since 1.1
3097 */
3098 public static byte[] toByteArray(final Reader reader, final String charsetName) throws IOException {
3099 return toByteArray(reader, Charsets.toCharset(charsetName));
3100 }
3101
3102 /**
3103 * Gets the contents of a {@link String} as a {@code byte[]}
3104 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}.
3105 * <p>
3106 * This is the same as {@link String#getBytes()}.
3107 * </p>
3108 *
3109 * @param input the {@link String} to convert.
3110 * @return the requested byte array.
3111 * @throws NullPointerException if the input is null.
3112 * @deprecated Use {@link String#getBytes()} instead.
3113 */
3114 @Deprecated
3115 public static byte[] toByteArray(final String input) {
3116 // make explicit the use of the default charset
3117 return input.getBytes(Charset.defaultCharset());
3118 }
3119
3120 /**
3121 * Gets the contents of a {@link URI} as a {@code byte[]}.
3122 *
3123 * @param uri the {@link URI} to read.
3124 * @return the requested byte array.
3125 * @throws NullPointerException if the uri is null.
3126 * @throws IOException if an I/O exception occurs.
3127 * @since 2.4
3128 */
3129 public static byte[] toByteArray(final URI uri) throws IOException {
3130 return toByteArray(uri.toURL());
3131 }
3132
3133 /**
3134 * Gets the contents of a {@link URL} as a {@code byte[]}.
3135 *
3136 * @param url the {@link URL} to read.
3137 * @return the requested byte array.
3138 * @throws NullPointerException if the input is null.
3139 * @throws IOException if an I/O exception occurs.
3140 * @since 2.4
3141 */
3142 public static byte[] toByteArray(final URL url) throws IOException {
3143 try (CloseableURLConnection urlConnection = CloseableURLConnection.open(url)) {
3144 return toByteArray(urlConnection);
3145 }
3146 }
3147
3148 /**
3149 * Gets the contents of a {@link URLConnection} as a {@code byte[]}.
3150 *
3151 * @param urlConnection the {@link URLConnection} to read.
3152 * @return the requested byte array.
3153 * @throws NullPointerException if the urlConn is null.
3154 * @throws IOException if an I/O exception occurs.
3155 * @since 2.4
3156 */
3157 public static byte[] toByteArray(final URLConnection urlConnection) throws IOException {
3158 try (InputStream inputStream = urlConnection.getInputStream()) {
3159 return toByteArray(inputStream);
3160 }
3161 }
3162
3163 /**
3164 * Gets the contents of an {@link InputStream} as a character array
3165 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}.
3166 * <p>
3167 * This method buffers the input internally, so there is no need to use a
3168 * {@link BufferedInputStream}.
3169 * </p>
3170 *
3171 * @param inputStream the {@link InputStream} to read.
3172 * @return the requested character array.
3173 * @throws NullPointerException if the input is null.
3174 * @throws IOException if an I/O error occurs.
3175 * @since 1.1
3176 * @deprecated Use {@link #toCharArray(InputStream, Charset)} instead
3177 */
3178 @Deprecated
3179 public static char[] toCharArray(final InputStream inputStream) throws IOException {
3180 return toCharArray(inputStream, Charset.defaultCharset());
3181 }
3182
3183 /**
3184 * Gets the contents of an {@link InputStream} as a character array
3185 * using the specified character encoding.
3186 * <p>
3187 * This method buffers the input internally, so there is no need to use a
3188 * {@link BufferedInputStream}.
3189 * </p>
3190 *
3191 * @param inputStream the {@link InputStream} to read.
3192 * @param charset the charset to use, null means platform default.
3193 * @return the requested character array.
3194 * @throws NullPointerException if the input is null.
3195 * @throws IOException if an I/O error occurs.
3196 * @since 2.3
3197 */
3198 public static char[] toCharArray(final InputStream inputStream, final Charset charset)
3199 throws IOException {
3200 final CharArrayWriter writer = new CharArrayWriter();
3201 copy(inputStream, writer, charset);
3202 return writer.toCharArray();
3203 }
3204
3205 /**
3206 * Gets the contents of an {@link InputStream} as a character array
3207 * using the specified character encoding.
3208 * <p>
3209 * Character encoding names can be found at
3210 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
3211 * </p>
3212 * <p>
3213 * This method buffers the input internally, so there is no need to use a
3214 * {@link BufferedInputStream}.
3215 * </p>
3216 *
3217 * @param inputStream the {@link InputStream} to read.
3218 * @param charsetName the name of the requested charset, null means platform default.
3219 * @return the requested character array.
3220 * @throws NullPointerException if the input is null.
3221 * @throws IOException if an I/O error occurs.
3222 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
3223 * @since 1.1
3224 */
3225 public static char[] toCharArray(final InputStream inputStream, final String charsetName) throws IOException {
3226 return toCharArray(inputStream, Charsets.toCharset(charsetName));
3227 }
3228
3229 /**
3230 * Gets the contents of a {@link Reader} as a character array.
3231 * <p>
3232 * This method buffers the input internally, so there is no need to use a
3233 * {@link BufferedReader}.
3234 * </p>
3235 *
3236 * @param reader the {@link Reader} to read.
3237 * @return the requested character array.
3238 * @throws NullPointerException if the input is null.
3239 * @throws IOException if an I/O error occurs.
3240 * @since 1.1
3241 */
3242 public static char[] toCharArray(final Reader reader) throws IOException {
3243 final CharArrayWriter sw = new CharArrayWriter();
3244 copy(reader, sw);
3245 return sw.toCharArray();
3246 }
3247
3248 /**
3249 * Converts the specified CharSequence to an input stream, encoded as bytes
3250 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}.
3251 *
3252 * @param input the CharSequence to convert.
3253 * @return an input stream.
3254 * @since 2.0
3255 * @deprecated Use {@link #toInputStream(CharSequence, Charset)} instead.
3256 */
3257 @Deprecated
3258 public static InputStream toInputStream(final CharSequence input) {
3259 return toInputStream(input, Charset.defaultCharset());
3260 }
3261
3262 /**
3263 * Converts the specified CharSequence to an input stream, encoded as bytes
3264 * using the specified character encoding.
3265 *
3266 * @param input the CharSequence to convert.
3267 * @param charset the charset to use, null means platform default.
3268 * @return an input stream.
3269 * @since 2.3
3270 */
3271 public static InputStream toInputStream(final CharSequence input, final Charset charset) {
3272 return toInputStream(input.toString(), charset);
3273 }
3274
3275 /**
3276 * Converts the specified CharSequence to an input stream, encoded as bytes
3277 * using the specified character encoding.
3278 * <p>
3279 * Character encoding names can be found at
3280 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
3281 * </p>
3282 *
3283 * @param input the CharSequence to convert.
3284 * @param charsetName the name of the requested charset, null means platform default.
3285 * @return an input stream.
3286 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
3287 * @since 2.0
3288 */
3289 public static InputStream toInputStream(final CharSequence input, final String charsetName) {
3290 return toInputStream(input, Charsets.toCharset(charsetName));
3291 }
3292
3293 /**
3294 * Converts the specified string to an input stream, encoded as bytes
3295 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}.
3296 *
3297 * @param input the string to convert.
3298 * @return an input stream.
3299 * @since 1.1
3300 * @deprecated Use {@link #toInputStream(String, Charset)} instead.
3301 */
3302 @Deprecated
3303 public static InputStream toInputStream(final String input) {
3304 return toInputStream(input, Charset.defaultCharset());
3305 }
3306
3307 /**
3308 * Converts the specified string to an input stream, encoded as bytes
3309 * using the specified character encoding.
3310 *
3311 * @param input the string to convert.
3312 * @param charset the charset to use, null means platform default.
3313 * @return an input stream.
3314 * @since 2.3
3315 */
3316 public static InputStream toInputStream(final String input, final Charset charset) {
3317 return new ByteArrayInputStream(input.getBytes(Charsets.toCharset(charset)));
3318 }
3319
3320 /**
3321 * Converts the specified string to an input stream, encoded as bytes
3322 * using the specified character encoding.
3323 * <p>
3324 * Character encoding names can be found at
3325 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
3326 * </p>
3327 *
3328 * @param input the string to convert.
3329 * @param charsetName the name of the requested charset, null means platform default.
3330 * @return an input stream.
3331 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
3332 * @since 1.1
3333 */
3334 public static InputStream toInputStream(final String input, final String charsetName) {
3335 return new ByteArrayInputStream(input.getBytes(Charsets.toCharset(charsetName)));
3336 }
3337
3338 /**
3339 * Gets the contents of a {@code byte[]} as a String
3340 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}.
3341 *
3342 * @param input the byte array to read.
3343 * @return the requested String.
3344 * @throws NullPointerException if the input is null.
3345 * @deprecated Use {@link String#String(byte[])} instead.
3346 */
3347 @Deprecated
3348 public static String toString(final byte[] input) {
3349 // make explicit the use of the default charset
3350 return new String(input, Charset.defaultCharset());
3351 }
3352
3353 /**
3354 * Gets the contents of a {@code byte[]} as a String
3355 * using the specified character encoding.
3356 * <p>
3357 * Character encoding names can be found at
3358 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
3359 * </p>
3360 *
3361 * @param input the byte array to read.
3362 * @param charsetName the name of the requested charset, null means platform default.
3363 * @return the requested String.
3364 * @throws NullPointerException if the input is null.
3365 */
3366 public static String toString(final byte[] input, final String charsetName) {
3367 return new String(input, Charsets.toCharset(charsetName));
3368 }
3369
3370 /**
3371 * Gets the contents of an {@link InputStream} as a String
3372 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}.
3373 * <p>
3374 * This method buffers the input internally, so there is no need to use a
3375 * {@link BufferedInputStream}.
3376 * </p>
3377 *
3378 * @param input the {@link InputStream} to read.
3379 * @return the requested String.
3380 * @throws NullPointerException if the input is null.
3381 * @throws IOException if an I/O error occurs.
3382 * @deprecated Use {@link #toString(InputStream, Charset)} instead.
3383 */
3384 @Deprecated
3385 public static String toString(final InputStream input) throws IOException {
3386 return toString(input, Charset.defaultCharset());
3387 }
3388
3389 /**
3390 * Gets the contents of an {@link InputStream} as a String
3391 * using the specified character encoding.
3392 * <p>
3393 * This method buffers the input internally, so there is no need to use a
3394 * {@link BufferedInputStream}.
3395 * </p>
3396 *
3397 * @param input the {@link InputStream} to read.
3398 * @param charset the charset to use, null means platform default.
3399 * @return the requested String.
3400 * @throws NullPointerException if the input is null.
3401 * @throws IOException if an I/O error occurs.
3402 * @since 2.3
3403 */
3404 public static String toString(final InputStream input, final Charset charset) throws IOException {
3405 try (StringBuilderWriter sw = new StringBuilderWriter()) {
3406 copy(input, sw, charset);
3407 return sw.toString();
3408 }
3409 }
3410
3411 /**
3412 * Gets the contents of an {@link InputStream} as a String
3413 * using the specified character encoding.
3414 * <p>
3415 * Character encoding names can be found at
3416 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
3417 * </p>
3418 * <p>
3419 * This method buffers the input internally, so there is no need to use a
3420 * {@link BufferedInputStream}.
3421 * </p>
3422 *
3423 * @param input the {@link InputStream} to read.
3424 * @param charsetName the name of the requested charset, null means platform default.
3425 * @return the requested String.
3426 * @throws NullPointerException if the input is null.
3427 * @throws IOException if an I/O error occurs.
3428 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
3429 */
3430 public static String toString(final InputStream input, final String charsetName)
3431 throws IOException {
3432 return toString(input, Charsets.toCharset(charsetName));
3433 }
3434
3435 /**
3436 * Gets the contents of an {@link InputStream} from a supplier as a String
3437 * using the specified character encoding.
3438 * <p>
3439 * This method buffers the input internally, so there is no need to use a
3440 * {@link BufferedInputStream}.
3441 * </p>
3442 *
3443 * @param input supplies the {@link InputStream} to read.
3444 * @param charset the charset to use, null means platform default.
3445 * @return the requested String.
3446 * @throws NullPointerException if the input is null.
3447 * @throws IOException if an I/O error occurs.
3448 * @since 2.12.0
3449 */
3450 public static String toString(final IOSupplier<InputStream> input, final Charset charset) throws IOException {
3451 return toString(input, charset, () -> {
3452 throw new NullPointerException("input");
3453 });
3454 }
3455
3456 /**
3457 * Gets the contents of an {@link InputStream} from a supplier as a String
3458 * using the specified character encoding.
3459 * <p>
3460 * This method buffers the input internally, so there is no need to use a
3461 * {@link BufferedInputStream}.
3462 * </p>
3463 *
3464 * @param input supplies the {@link InputStream} to read.
3465 * @param charset the charset to use, null means platform default.
3466 * @param defaultString the default return value if the supplier or its value is null.
3467 * @return the requested String.
3468 * @throws NullPointerException if the input is null.
3469 * @throws IOException if an I/O error occurs.
3470 * @since 2.12.0
3471 */
3472 public static String toString(final IOSupplier<InputStream> input, final Charset charset, final IOSupplier<String> defaultString) throws IOException {
3473 if (input == null) {
3474 return defaultString.get();
3475 }
3476 try (InputStream inputStream = input.get()) {
3477 return inputStream != null ? toString(inputStream, charset) : defaultString.get();
3478 }
3479 }
3480
3481 /**
3482 * Gets the contents of a {@link Reader} as a String.
3483 * <p>
3484 * This method buffers the input internally, so there is no need to use a
3485 * {@link BufferedReader}.
3486 * </p>
3487 *
3488 * @param reader the {@link Reader} to read.
3489 * @return the requested String.
3490 * @throws NullPointerException if the input is null.
3491 * @throws IOException if an I/O error occurs.
3492 */
3493 public static String toString(final Reader reader) throws IOException {
3494 try (StringBuilderWriter sw = new StringBuilderWriter()) {
3495 copy(reader, sw);
3496 return sw.toString();
3497 }
3498 }
3499
3500 /**
3501 * Gets the contents at the given URI using the virtual machine's {@linkplain Charset#defaultCharset() default charset}.
3502 *
3503 * @param uri The URI source.
3504 * @return The contents of the URL as a String.
3505 * @throws IOException if an I/O exception occurs.
3506 * @since 2.1
3507 * @deprecated Use {@link #toString(URI, Charset)} instead.
3508 */
3509 @Deprecated
3510 public static String toString(final URI uri) throws IOException {
3511 return toString(uri, Charset.defaultCharset());
3512 }
3513
3514 /**
3515 * Gets the contents at the given URI.
3516 *
3517 * @param uri The URI source.
3518 * @param encoding The encoding name for the URL contents.
3519 * @return The contents of the URL as a String.
3520 * @throws IOException if an I/O exception occurs.
3521 * @since 2.3.
3522 */
3523 public static String toString(final URI uri, final Charset encoding) throws IOException {
3524 return toString(uri.toURL(), Charsets.toCharset(encoding));
3525 }
3526
3527 /**
3528 * Gets the contents at the given URI.
3529 *
3530 * @param uri The URI source.
3531 * @param charsetName The encoding name for the URL contents.
3532 * @return The contents of the URL as a String.
3533 * @throws IOException if an I/O exception occurs.
3534 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
3535 * @since 2.1
3536 */
3537 public static String toString(final URI uri, final String charsetName) throws IOException {
3538 return toString(uri, Charsets.toCharset(charsetName));
3539 }
3540
3541 /**
3542 * Gets the contents at the given URL using the virtual machine's {@linkplain Charset#defaultCharset() default charset}.
3543 *
3544 * @param url The URL source.
3545 * @return The contents of the URL as a String.
3546 * @throws IOException if an I/O exception occurs.
3547 * @since 2.1
3548 * @deprecated Use {@link #toString(URL, Charset)} instead.
3549 */
3550 @Deprecated
3551 public static String toString(final URL url) throws IOException {
3552 return toString(url, Charset.defaultCharset());
3553 }
3554
3555 /**
3556 * Gets the contents at the given URL.
3557 *
3558 * @param url The URL source.
3559 * @param encoding The encoding name for the URL contents.
3560 * @return The contents of the URL as a String.
3561 * @throws IOException if an I/O exception occurs.
3562 * @since 2.3
3563 */
3564 public static String toString(final URL url, final Charset encoding) throws IOException {
3565 return toString(url::openStream, encoding);
3566 }
3567
3568 /**
3569 * Gets the contents at the given URL.
3570 *
3571 * @param url The URL source.
3572 * @param charsetName The encoding name for the URL contents.
3573 * @return The contents of the URL as a String.
3574 * @throws IOException if an I/O exception occurs.
3575 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
3576 * @since 2.1
3577 */
3578 public static String toString(final URL url, final String charsetName) throws IOException {
3579 return toString(url, Charsets.toCharset(charsetName));
3580 }
3581
3582 /**
3583 * Writes bytes from a {@code byte[]} to an {@link OutputStream}.
3584 *
3585 * @param data the byte array to write, do not modify during output, null ignored.
3586 * @param output the {@link OutputStream} to write to.
3587 * @throws NullPointerException if output is null.
3588 * @throws IOException if an I/O error occurs.
3589 * @since 1.1
3590 */
3591 public static void write(final byte[] data, final OutputStream output)
3592 throws IOException {
3593 if (data != null) {
3594 output.write(data);
3595 }
3596 }
3597
3598 /**
3599 * Writes bytes from a {@code byte[]} to chars on a {@link Writer}
3600 * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}.
3601 * <p>
3602 * This method uses {@link String#String(byte[])}.
3603 * </p>
3604 *
3605 * @param data the byte array to write, do not modify during output,
3606 * null ignored
3607 * @param writer the {@link Writer} to write to.
3608 * @throws NullPointerException if output is null.
3609 * @throws IOException if an I/O error occurs.
3610 * @since 1.1
3611 * @deprecated Use {@link #write(byte[], Writer, Charset)} instead.
3612 */
3613 @Deprecated
3614 public static void write(final byte[] data, final Writer writer) throws IOException {
3615 write(data, writer, Charset.defaultCharset());
3616 }
3617
3618 /**
3619 * Writes bytes from a {@code byte[]} to chars on a {@link Writer}
3620 * using the specified character encoding.
3621 * <p>
3622 * This method uses {@link String#String(byte[], String)}.
3623 * </p>
3624 *
3625 * @param data the byte array to write, do not modify during output,
3626 * null ignored
3627 * @param writer the {@link Writer} to write to.
3628 * @param charset the charset to use, null means platform default.
3629 * @throws NullPointerException if output is null.
3630 * @throws IOException if an I/O error occurs.
3631 * @since 2.3
3632 */
3633 public static void write(final byte[] data, final Writer writer, final Charset charset) throws IOException {
3634 if (data != null) {
3635 writer.write(new String(data, Charsets.toCharset(charset)));
3636 }
3637 }
3638
3639 /**
3640 * Writes bytes from a {@code byte[]} to chars on a {@link Writer} using the specified character encoding.
3641 * <p>
3642 * Character encoding names can be found at <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
3643 * </p>
3644 * <p>
3645 * This method uses {@link String#String(byte[], String)}.
3646 * </p>
3647 *
3648 * @param data the byte array to write, do not modify during output, null ignored.
3649 * @param writer the {@link Writer} to write to.
3650 * @param charsetName the name of the requested charset, null means platform default.
3651 * @throws NullPointerException if output is null.
3652 * @throws IOException if an I/O error occurs.
3653 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
3654 * @since 1.1
3655 */
3656 public static void write(final byte[] data, final Writer writer, final String charsetName) throws IOException {
3657 write(data, writer, Charsets.toCharset(charsetName));
3658 }
3659
3660 /**
3661 * Writes chars from a {@code char[]} to bytes on an {@link OutputStream}.
3662 * <p>
3663 * This method uses the virtual machine's {@linkplain Charset#defaultCharset() default charset}.
3664 * </p>
3665 *
3666 * @param data the char array to write, do not modify during output, null ignored.
3667 * @param output the {@link OutputStream} to write to.
3668 * @throws NullPointerException if output is null.
3669 * @throws IOException if an I/O error occurs.
3670 * @since 1.1
3671 * @deprecated Use {@link #write(char[], OutputStream, Charset)} instead.
3672 */
3673 @Deprecated
3674 public static void write(final char[] data, final OutputStream output)
3675 throws IOException {
3676 write(data, output, Charset.defaultCharset());
3677 }
3678
3679 /**
3680 * Writes chars from a {@code char[]} to bytes on an {@link OutputStream} using the specified character encoding.
3681 * <p>
3682 * This method uses {@link String#String(char[])} and {@link String#getBytes(String)}.
3683 * </p>
3684 *
3685 * @param data the char array to write, do not modify during output, null ignored.
3686 * @param output the {@link OutputStream} to write to.
3687 * @param charset the charset to use, null means platform default.
3688 * @throws NullPointerException if output is null.
3689 * @throws IOException if an I/O error occurs.
3690 * @since 2.3
3691 */
3692 public static void write(final char[] data, final OutputStream output, final Charset charset) throws IOException {
3693 if (data != null) {
3694 write(new String(data), output, charset);
3695 }
3696 }
3697
3698 /**
3699 * Writes chars from a {@code char[]} to bytes on an {@link OutputStream} using the specified character encoding.
3700 * <p>
3701 * Character encoding names can be found at <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
3702 * </p>
3703 * <p>
3704 * This method uses {@link String#String(char[])} and {@link String#getBytes(String)}.
3705 * </p>
3706 *
3707 * @param data the char array to write, do not modify during output, null ignored.
3708 * @param output the {@link OutputStream} to write to.
3709 * @param charsetName the name of the requested charset, null means platform default.
3710 * @throws NullPointerException if output is null.
3711 * @throws IOException if an I/O error occurs.
3712 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
3713 * @since 1.1
3714 */
3715 public static void write(final char[] data, final OutputStream output, final String charsetName)
3716 throws IOException {
3717 write(data, output, Charsets.toCharset(charsetName));
3718 }
3719
3720 /**
3721 * Writes chars from a {@code char[]} to a {@link Writer}
3722 *
3723 * @param data the char array to write, do not modify during output, null ignored.
3724 * @param writer the {@link Writer} to write to.
3725 * @throws NullPointerException if output is null.
3726 * @throws IOException if an I/O error occurs.
3727 * @since 1.1
3728 */
3729 public static void write(final char[] data, final Writer writer) throws IOException {
3730 if (data != null) {
3731 writer.write(data);
3732 }
3733 }
3734
3735 /**
3736 * Writes chars from a {@link CharSequence} to bytes on an {@link OutputStream} using the virtual machine's {@link Charset#defaultCharset() default
3737 * charset}.
3738 * <p>
3739 * This method uses {@link String#getBytes()}.
3740 * </p>
3741 *
3742 * @param data the {@link CharSequence} to write, null ignored.
3743 * @param output the {@link OutputStream} to write to.
3744 * @throws NullPointerException if output is null.
3745 * @throws IOException if an I/O error occurs.
3746 * @since 2.0
3747 * @deprecated Use {@link #write(CharSequence, OutputStream, Charset)} instead.
3748 */
3749 @Deprecated
3750 public static void write(final CharSequence data, final OutputStream output)
3751 throws IOException {
3752 write(data, output, Charset.defaultCharset());
3753 }
3754
3755 /**
3756 * Writes chars from a {@link CharSequence} to bytes on an {@link OutputStream} using the specified character encoding.
3757 * <p>
3758 * This method uses {@link String#getBytes(String)}.
3759 * </p>
3760 *
3761 * @param data the {@link CharSequence} to write, null ignored.
3762 * @param output the {@link OutputStream} to write to.
3763 * @param charset the charset to use, null means platform default.
3764 * @throws NullPointerException if output is null.
3765 * @throws IOException if an I/O error occurs.
3766 * @since 2.3
3767 */
3768 public static void write(final CharSequence data, final OutputStream output, final Charset charset)
3769 throws IOException {
3770 if (data != null) {
3771 write(data.toString(), output, charset);
3772 }
3773 }
3774
3775 /**
3776 * Writes chars from a {@link CharSequence} to bytes on an {@link OutputStream} using the specified character encoding.
3777 * <p>
3778 * Character encoding names can be found at <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
3779 * </p>
3780 * <p>
3781 * This method uses {@link String#getBytes(String)}.
3782 * </p>
3783 *
3784 * @param data the {@link CharSequence} to write, null ignored.
3785 * @param output the {@link OutputStream} to write to.
3786 * @param charsetName the name of the requested charset, null means platform default.
3787 * @throws NullPointerException if output is null.
3788 * @throws IOException if an I/O error occurs.
3789 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
3790 * @since 2.0
3791 */
3792 public static void write(final CharSequence data, final OutputStream output, final String charsetName)
3793 throws IOException {
3794 write(data, output, Charsets.toCharset(charsetName));
3795 }
3796
3797 /**
3798 * Writes chars from a {@link CharSequence} to a {@link Writer}.
3799 *
3800 * @param data the {@link CharSequence} to write, null ignored.
3801 * @param writer the {@link Writer} to write to.
3802 * @throws NullPointerException if output is null.
3803 * @throws IOException if an I/O error occurs.
3804 * @since 2.0
3805 */
3806 public static void write(final CharSequence data, final Writer writer) throws IOException {
3807 if (data != null) {
3808 write(data.toString(), writer);
3809 }
3810 }
3811
3812 /**
3813 * Writes chars from a {@link String} to bytes on an
3814 * {@link OutputStream} using the virtual machine's {@linkplain Charset#defaultCharset() default charset}.
3815 * <p>
3816 * This method uses {@link String#getBytes()}.
3817 * </p>
3818 *
3819 * @param data the {@link String} to write, null ignored.
3820 * @param output the {@link OutputStream} to write to.
3821 * @throws NullPointerException if output is null.
3822 * @throws IOException if an I/O error occurs.
3823 * @since 1.1
3824 * @deprecated Use {@link #write(String, OutputStream, Charset)} instead
3825 */
3826 @Deprecated
3827 public static void write(final String data, final OutputStream output)
3828 throws IOException {
3829 write(data, output, Charset.defaultCharset());
3830 }
3831
3832 /**
3833 * Writes chars from a {@link String} to bytes on an
3834 * {@link OutputStream} using the specified character encoding.
3835 * <p>
3836 * This method uses {@link String#getBytes(String)}.
3837 * </p>
3838 *
3839 * @param data the {@link String} to write, null ignored.
3840 * @param output the {@link OutputStream} to write to.
3841 * @param charset the charset to use, null means platform default.
3842 * @throws NullPointerException if output is null.
3843 * @throws IOException if an I/O error occurs.
3844 * @since 2.3
3845 */
3846 @SuppressWarnings("resource")
3847 public static void write(final String data, final OutputStream output, final Charset charset) throws IOException {
3848 if (data != null) {
3849 // Use Charset#encode(String), since calling String#getBytes(Charset) might result in
3850 // NegativeArraySizeException or OutOfMemoryError.
3851 // The underlying OutputStream should not be closed, so the channel is not closed.
3852 Channels.newChannel(output).write(Charsets.toCharset(charset).encode(data));
3853 }
3854 }
3855
3856 /**
3857 * Writes chars from a {@link String} to bytes on an
3858 * {@link OutputStream} using the specified character encoding.
3859 * <p>
3860 * Character encoding names can be found at
3861 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
3862 * </p>
3863 * <p>
3864 * This method uses {@link String#getBytes(String)}.
3865 * </p>
3866 *
3867 * @param data the {@link String} to write, null ignored.
3868 * @param output the {@link OutputStream} to write to.
3869 * @param charsetName the name of the requested charset, null means platform default.
3870 * @throws NullPointerException if output is null.
3871 * @throws IOException if an I/O error occurs.
3872 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
3873 * @since 1.1
3874 */
3875 public static void write(final String data, final OutputStream output, final String charsetName)
3876 throws IOException {
3877 write(data, output, Charsets.toCharset(charsetName));
3878 }
3879
3880 /**
3881 * Writes chars from a {@link String} to a {@link Writer}.
3882 *
3883 * @param data the {@link String} to write, null ignored.
3884 * @param writer the {@link Writer} to write to.
3885 * @throws NullPointerException if output is null.
3886 * @throws IOException if an I/O error occurs.
3887 * @since 1.1
3888 */
3889 public static void write(final String data, final Writer writer) throws IOException {
3890 if (data != null) {
3891 writer.write(data);
3892 }
3893 }
3894
3895 /**
3896 * Writes chars from a {@link StringBuffer} to bytes on an
3897 * {@link OutputStream} using the default character encoding of the
3898 * platform.
3899 * <p>
3900 * This method uses {@link String#getBytes()}.
3901 * </p>
3902 *
3903 * @param data the {@link StringBuffer} to write, null ignored.
3904 * @param output the {@link OutputStream} to write to.
3905 * @throws NullPointerException if output is null.
3906 * @throws IOException if an I/O error occurs
3907 * @since 1.1
3908 * @deprecated Use {@link #write(CharSequence, OutputStream)}.
3909 */
3910 @Deprecated
3911 public static void write(final StringBuffer data, final OutputStream output) //NOSONAR
3912 throws IOException {
3913 write(data, output, (String) null);
3914 }
3915
3916 /**
3917 * Writes chars from a {@link StringBuffer} to bytes on an
3918 * {@link OutputStream} using the specified character encoding.
3919 * <p>
3920 * Character encoding names can be found at
3921 * <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
3922 * </p>
3923 * <p>
3924 * This method uses {@link String#getBytes(String)}.
3925 * </p>
3926 *
3927 * @param data the {@link StringBuffer} to write, null ignored.
3928 * @param output the {@link OutputStream} to write to.
3929 * @param charsetName the name of the requested charset, null means platform default.
3930 * @throws NullPointerException if output is null.
3931 * @throws IOException if an I/O error occurs.
3932 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
3933 * @since 1.1
3934 * @deprecated Use {@link #write(CharSequence, OutputStream, String)}.
3935 */
3936 @Deprecated
3937 public static void write(final StringBuffer data, final OutputStream output, final String charsetName) //NOSONAR
3938 throws IOException {
3939 if (data != null) {
3940 write(data.toString(), output, Charsets.toCharset(charsetName));
3941 }
3942 }
3943
3944 /**
3945 * Writes chars from a {@link StringBuffer} to a {@link Writer}.
3946 *
3947 * @param data the {@link StringBuffer} to write, null ignored.
3948 * @param writer the {@link Writer} to write to.
3949 * @throws NullPointerException if output is null.
3950 * @throws IOException if an I/O error occurs.
3951 * @since 1.1
3952 * @deprecated Use {@link #write(CharSequence, Writer)}.
3953 */
3954 @Deprecated
3955 public static void write(final StringBuffer data, final Writer writer) //NOSONAR
3956 throws IOException {
3957 if (data != null) {
3958 writer.write(data.toString());
3959 }
3960 }
3961
3962 /**
3963 * Writes bytes from a {@code byte[]} to an {@link OutputStream} using chunked writes.
3964 * This is intended for writing very large byte arrays which might otherwise cause excessive
3965 * memory usage if the native code has to allocate a copy.
3966 *
3967 * @param data the byte array to write, do not modify during output,
3968 * null ignored.
3969 * @param output the {@link OutputStream} to write to.
3970 * @throws NullPointerException if output is null.
3971 * @throws IOException if an I/O error occurs.
3972 * @since 2.5
3973 */
3974 public static void writeChunked(final byte[] data, final OutputStream output)
3975 throws IOException {
3976 if (data != null) {
3977 int bytes = data.length;
3978 int offset = 0;
3979 while (bytes > 0) {
3980 final int chunk = Math.min(bytes, DEFAULT_BUFFER_SIZE);
3981 output.write(data, offset, chunk);
3982 bytes -= chunk;
3983 offset += chunk;
3984 }
3985 }
3986 }
3987
3988 /**
3989 * Writes chars from a {@code char[]} to a {@link Writer} using chunked writes. This is intended for writing very large byte arrays which might otherwise
3990 * cause excessive memory usage if the native code has to allocate a copy.
3991 *
3992 * @param data the char array to write, do not modify during output, null ignored.
3993 * @param writer the {@link Writer} to write to.
3994 * @throws NullPointerException if output is null.
3995 * @throws IOException if an I/O error occurs.
3996 * @since 2.5
3997 */
3998 public static void writeChunked(final char[] data, final Writer writer) throws IOException {
3999 if (data != null) {
4000 int bytes = data.length;
4001 int offset = 0;
4002 while (bytes > 0) {
4003 final int chunk = Math.min(bytes, DEFAULT_BUFFER_SIZE);
4004 writer.write(data, offset, chunk);
4005 bytes -= chunk;
4006 offset += chunk;
4007 }
4008 }
4009 }
4010
4011 /**
4012 * Writes the {@link #toString()} value of each item in a collection to an {@link OutputStream} line by line, using the virtual machine's
4013 * {@linkplain Charset#defaultCharset() default charset} and the specified line ending.
4014 *
4015 * @param lines the lines to write, null entries produce blank lines.
4016 * @param lineEnding the line separator to use, null is system default.
4017 * @param output the {@link OutputStream} to write to, not null, not closed.
4018 * @throws NullPointerException if the output is null.
4019 * @throws IOException if an I/O error occurs.
4020 * @since 1.1
4021 * @deprecated Use {@link #writeLines(Collection, String, OutputStream, Charset)} instead
4022 */
4023 @Deprecated
4024 public static void writeLines(final Collection<?> lines, final String lineEnding, final OutputStream output) throws IOException {
4025 writeLines(lines, lineEnding, output, Charset.defaultCharset());
4026 }
4027
4028 /**
4029 * Writes the {@link #toString()} value of each item in a collection to an {@link OutputStream} line by line, using the specified character encoding and the
4030 * specified line ending.
4031 * <p>
4032 * UTF-16 is written big-endian with no byte order mark. For little-endian, use UTF-16LE. For a BOM, write it to the stream before calling this method.
4033 * </p>
4034 *
4035 * @param lines the lines to write, null entries produce blank lines.
4036 * @param lineEnding the line separator to use, null is system default.
4037 * @param output the {@link OutputStream} to write to, not null, not closed.
4038 * @param charset the charset to use, null means platform default.
4039 * @throws NullPointerException if output is null.
4040 * @throws IOException if an I/O error occurs.
4041 * @since 2.3
4042 */
4043 public static void writeLines(final Collection<?> lines, String lineEnding, final OutputStream output, Charset charset) throws IOException {
4044 if (lines == null) {
4045 return;
4046 }
4047 if (lineEnding == null) {
4048 lineEnding = System.lineSeparator();
4049 }
4050 if (StandardCharsets.UTF_16.equals(charset)) {
4051 // don't write a BOM
4052 charset = StandardCharsets.UTF_16BE;
4053 }
4054 final byte[] eolBytes = lineEnding.getBytes(charset);
4055 for (final Object line : lines) {
4056 if (line != null) {
4057 write(line.toString(), output, charset);
4058 }
4059 output.write(eolBytes);
4060 }
4061 }
4062
4063 /**
4064 * Writes the {@link #toString()} value of each item in a collection to an {@link OutputStream} line by line, using the specified character encoding and the
4065 * specified line ending.
4066 * <p>
4067 * Character encoding names can be found at <a href="https://www.iana.org/assignments/character-sets">IANA</a>.
4068 * </p>
4069 *
4070 * @param lines the lines to write, null entries produce blank lines.
4071 * @param lineEnding the line separator to use, null is system default.
4072 * @param output the {@link OutputStream} to write to, not null, not closed.
4073 * @param charsetName the name of the requested charset, null means platform default.
4074 * @throws NullPointerException if the output is null.
4075 * @throws IOException if an I/O error occurs.
4076 * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported.
4077 * @since 1.1
4078 */
4079 public static void writeLines(final Collection<?> lines, final String lineEnding, final OutputStream output, final String charsetName) throws IOException {
4080 writeLines(lines, lineEnding, output, Charsets.toCharset(charsetName));
4081 }
4082
4083 /**
4084 * Writes the {@link #toString()} value of each item in a collection to a {@link Writer} line by line, using the specified line ending.
4085 *
4086 * @param lines the lines to write, null entries produce blank lines.
4087 * @param lineEnding the line separator to use, null is system default.
4088 * @param writer the {@link Writer} to write to, not null, not closed.
4089 * @throws NullPointerException if the input is null.
4090 * @throws IOException if an I/O error occurs.
4091 * @since 1.1
4092 */
4093 public static void writeLines(final Collection<?> lines, String lineEnding, final Writer writer) throws IOException {
4094 if (lines == null) {
4095 return;
4096 }
4097 if (lineEnding == null) {
4098 lineEnding = System.lineSeparator();
4099 }
4100 for (final Object line : lines) {
4101 if (line != null) {
4102 writer.write(line.toString());
4103 }
4104 writer.write(lineEnding);
4105 }
4106 }
4107
4108 /**
4109 * Returns the given Appendable if it is already a {@link Writer}, otherwise creates a Writer wrapper around the
4110 * given Appendable.
4111 *
4112 * @param appendable the Appendable to wrap or return (not null).
4113 * @return the given Appendable or a Writer wrapper around the given Appendable.
4114 * @throws NullPointerException if the input parameter is null.
4115 * @since 2.7
4116 */
4117 public static Writer writer(final Appendable appendable) {
4118 Objects.requireNonNull(appendable, "appendable");
4119 if (appendable instanceof Writer) {
4120 return (Writer) appendable;
4121 }
4122 if (appendable instanceof StringBuilder) {
4123 return new StringBuilderWriter((StringBuilder) appendable);
4124 }
4125 return new AppendableWriter<>(appendable);
4126 }
4127
4128 /**
4129 * Instances should NOT be constructed in standard programming.
4130 *
4131 * @deprecated TODO Make private in 3.0.
4132 */
4133 @Deprecated
4134 public IOUtils() { //NOSONAR
4135 // empty
4136 }
4137
4138 }