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