View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.io;
18  
19  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
20  import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertFalse;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertNotSame;
25  import static org.junit.jupiter.api.Assertions.assertNull;
26  import static org.junit.jupiter.api.Assertions.assertSame;
27  import static org.junit.jupiter.api.Assertions.assertThrows;
28  import static org.junit.jupiter.api.Assertions.assertTrue;
29  import static org.junit.jupiter.api.Assertions.fail;
30  
31  import java.io.BufferedInputStream;
32  import java.io.BufferedOutputStream;
33  import java.io.BufferedReader;
34  import java.io.BufferedWriter;
35  import java.io.ByteArrayInputStream;
36  import java.io.ByteArrayOutputStream;
37  import java.io.CharArrayReader;
38  import java.io.CharArrayWriter;
39  import java.io.Closeable;
40  import java.io.EOFException;
41  import java.io.File;
42  import java.io.FileInputStream;
43  import java.io.IOException;
44  import java.io.InputStream;
45  import java.io.InputStreamReader;
46  import java.io.OutputStream;
47  import java.io.Reader;
48  import java.io.StringReader;
49  import java.io.Writer;
50  import java.net.ServerSocket;
51  import java.net.Socket;
52  import java.net.URI;
53  import java.net.URL;
54  import java.net.URLConnection;
55  import java.nio.ByteBuffer;
56  import java.nio.channels.FileChannel;
57  import java.nio.channels.Selector;
58  import java.nio.charset.Charset;
59  import java.nio.charset.StandardCharsets;
60  import java.nio.file.Files;
61  import java.nio.file.Path;
62  import java.util.Arrays;
63  import java.util.List;
64  import java.util.function.Supplier;
65  import java.util.stream.Stream;
66  
67  import org.apache.commons.io.function.IOConsumer;
68  import org.apache.commons.io.input.BrokenInputStream;
69  import org.apache.commons.io.input.CharSequenceInputStream;
70  import org.apache.commons.io.input.CircularInputStream;
71  import org.apache.commons.io.input.NullInputStream;
72  import org.apache.commons.io.input.NullReader;
73  import org.apache.commons.io.output.AppendableWriter;
74  import org.apache.commons.io.output.BrokenOutputStream;
75  import org.apache.commons.io.output.CountingOutputStream;
76  import org.apache.commons.io.output.NullOutputStream;
77  import org.apache.commons.io.output.NullWriter;
78  import org.apache.commons.io.output.StringBuilderWriter;
79  import org.apache.commons.io.test.TestUtils;
80  import org.apache.commons.io.test.ThrowOnCloseReader;
81  import org.apache.commons.lang3.StringUtils;
82  import org.junit.jupiter.api.AfterAll;
83  import org.junit.jupiter.api.BeforeAll;
84  import org.junit.jupiter.api.BeforeEach;
85  import org.junit.jupiter.api.Disabled;
86  import org.junit.jupiter.api.Test;
87  import org.junit.jupiter.api.io.TempDir;
88  
89  /**
90   * This is used to test {@link IOUtils} for correctness. The following checks are performed:
91   * <ul>
92   * <li>The return must not be null, must be the same type and equals() to the method's second arg</li>
93   * <li>All bytes must have been read from the source (available() == 0)</li>
94   * <li>The source and destination content must be identical (byte-wise comparison check)</li>
95   * <li>The output stream must not have been closed (a byte/char is written to test this, and subsequent size
96   * checked)</li>
97   * </ul>
98   * Due to interdependencies in IOUtils and IOUtilsTest, one bug may cause multiple tests to fail.
99   */
100 @SuppressWarnings("deprecation") // deliberately testing deprecated code
101 public class IOUtilsTest {
102 
103     private static final String UTF_8 = StandardCharsets.UTF_8.name();
104 
105     private static final int FILE_SIZE = 1024 * 4 + 1;
106 
107     /** Determine if this is windows. */
108     private static final boolean WINDOWS = File.separatorChar == '\\';
109 
110     /*
111      * Note: this is not particularly beautiful code. A better way to check for flush and close status would be to
112      * implement "trojan horse" wrapper implementations of the various stream classes, which set a flag when relevant
113      * methods are called. (JT)
114      */
115 
116     @BeforeAll
117     @AfterAll
118     public static void beforeAll() {
119         // Not required, just to exercise the method and make sure there are no adverse side-effect when recycling thread locals.
120         IO.clear();
121     }
122 
123     @TempDir
124     public File temporaryFolder;
125 
126     private char[] carr;
127 
128     private byte[] iarr;
129 
130     private File testFile;
131 
132     /**
133      * Path constructed from {@code testFile}.
134      */
135     private Path testFilePath;
136 
137     /** Assert that the contents of two byte arrays are the same. */
138     private void assertEqualContent(final byte[] b0, final byte[] b1) {
139         assertArrayEquals(b0, b1, "Content not equal according to java.util.Arrays#equals()");
140     }
141 
142     @BeforeEach
143     public void setUp() {
144         try {
145             testFile = new File(temporaryFolder, "file2-test.txt");
146             testFilePath = testFile.toPath();
147 
148             if (!testFile.getParentFile().exists()) {
149                 throw new IOException("Cannot create file " + testFile + " as the parent directory does not exist");
150             }
151             try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(testFilePath))) {
152                 TestUtils.generateTestData(output, FILE_SIZE);
153             }
154         } catch (final IOException e) {
155             fail("Can't run this test because the environment could not be built: " + e.getMessage());
156         }
157         // Create and init a byte array as input data
158         iarr = new byte[200];
159         Arrays.fill(iarr, (byte) -1);
160         for (int i = 0; i < 80; i++) {
161             iarr[i] = (byte) i;
162         }
163         carr = new char[200];
164         Arrays.fill(carr, (char) -1);
165         for (int i = 0; i < 80; i++) {
166             carr[i] = (char) i;
167         }
168     }
169 
170     @Test
171     public void testAsBufferedInputStream() {
172         final InputStream is = new InputStream() {
173             @Override
174             public int read() throws IOException {
175                 return 0;
176             }
177         };
178         final BufferedInputStream bis = IOUtils.buffer(is);
179         assertNotSame(is, bis);
180         assertSame(bis, IOUtils.buffer(bis));
181     }
182 
183     @Test
184     public void testAsBufferedInputStreamWithBufferSize() {
185         final InputStream is = new InputStream() {
186             @Override
187             public int read() throws IOException {
188                 return 0;
189             }
190         };
191         final BufferedInputStream bis = IOUtils.buffer(is, 2048);
192         assertNotSame(is, bis);
193         assertSame(bis, IOUtils.buffer(bis));
194         assertSame(bis, IOUtils.buffer(bis, 1024));
195     }
196 
197     @Test
198     public void testAsBufferedNull() {
199         final String npeExpectedMessage = "Expected NullPointerException";
200         assertThrows(NullPointerException.class, () -> IOUtils.buffer((InputStream) null), npeExpectedMessage);
201         assertThrows(NullPointerException.class, () -> IOUtils.buffer((OutputStream) null), npeExpectedMessage);
202         assertThrows(NullPointerException.class, () -> IOUtils.buffer((Reader) null), npeExpectedMessage);
203         assertThrows(NullPointerException.class, () -> IOUtils.buffer((Writer) null), npeExpectedMessage);
204     }
205 
206     @Test
207     public void testAsBufferedOutputStream() {
208         final OutputStream is = new OutputStream() {
209             @Override
210             public void write(final int b) throws IOException {
211             }
212         };
213         final BufferedOutputStream bis = IOUtils.buffer(is);
214         assertNotSame(is, bis);
215         assertSame(bis, IOUtils.buffer(bis));
216     }
217 
218     @Test
219     public void testAsBufferedOutputStreamWithBufferSize() {
220         final OutputStream os = new OutputStream() {
221             @Override
222             public void write(final int b) throws IOException {
223             }
224         };
225         final BufferedOutputStream bos = IOUtils.buffer(os, 2048);
226         assertNotSame(os, bos);
227         assertSame(bos, IOUtils.buffer(bos));
228         assertSame(bos, IOUtils.buffer(bos, 1024));
229     }
230 
231     @Test
232     public void testAsBufferedReader() {
233         final Reader is = new Reader() {
234             @Override
235             public void close() throws IOException {
236             }
237 
238             @Override
239             public int read(final char[] cbuf, final int off, final int len) throws IOException {
240                 return 0;
241             }
242         };
243         final BufferedReader bis = IOUtils.buffer(is);
244         assertNotSame(is, bis);
245         assertSame(bis, IOUtils.buffer(bis));
246     }
247 
248     @Test
249     public void testAsBufferedReaderWithBufferSize() {
250         final Reader r = new Reader() {
251             @Override
252             public void close() throws IOException {
253             }
254 
255             @Override
256             public int read(final char[] cbuf, final int off, final int len) throws IOException {
257                 return 0;
258             }
259         };
260         final BufferedReader br = IOUtils.buffer(r, 2048);
261         assertNotSame(r, br);
262         assertSame(br, IOUtils.buffer(br));
263         assertSame(br, IOUtils.buffer(br, 1024));
264     }
265 
266     @Test
267     public void testAsBufferedWriter() {
268         final Writer nullWriter = NullWriter.INSTANCE;
269         final BufferedWriter bis = IOUtils.buffer(nullWriter);
270         assertNotSame(nullWriter, bis);
271         assertSame(bis, IOUtils.buffer(bis));
272     }
273 
274     @Test
275     public void testAsBufferedWriterWithBufferSize() {
276         final Writer nullWriter = NullWriter.INSTANCE;
277         final BufferedWriter bw = IOUtils.buffer(nullWriter, 2024);
278         assertNotSame(nullWriter, bw);
279         assertSame(bw, IOUtils.buffer(bw));
280         assertSame(bw, IOUtils.buffer(bw, 1024));
281     }
282 
283     @Test
284     public void testAsWriterAppendable() throws IOException {
285         final Appendable a = new StringBuffer();
286         try (Writer w = IOUtils.writer(a)) {
287             assertNotSame(w, a);
288             assertEquals(AppendableWriter.class, w.getClass());
289             assertSame(w, IOUtils.writer(w));
290         }
291     }
292 
293     @Test
294     public void testAsWriterNull() {
295         assertThrows(NullPointerException.class, () -> IOUtils.writer(null));
296     }
297 
298     @Test
299     public void testAsWriterStringBuilder() throws IOException {
300         final Appendable a = new StringBuilder();
301         try (Writer w = IOUtils.writer(a)) {
302             assertNotSame(w, a);
303             assertEquals(StringBuilderWriter.class, w.getClass());
304             assertSame(w, IOUtils.writer(w));
305         }
306     }
307 
308     @Test
309     public void testByteArrayWithNegativeSize() {
310         assertThrows(NegativeArraySizeException.class, () -> IOUtils.byteArray(-1));
311     }
312 
313     @Test
314     public void testClose() {
315         assertDoesNotThrow(() -> IOUtils.close((Closeable) null));
316         assertDoesNotThrow(() -> IOUtils.close(new StringReader("s")));
317         assertThrows(IOException.class, () -> IOUtils.close(new ThrowOnCloseReader(new StringReader("s"))));
318     }
319 
320     @Test
321     public void testCloseConsumer() {
322         final Closeable nullCloseable = null;
323         assertDoesNotThrow(() -> IOUtils.close(nullCloseable, null)); // null consumer
324         assertDoesNotThrow(() -> IOUtils.close(new StringReader("s"), null)); // null consumer
325         assertDoesNotThrow(() -> IOUtils.close(new ThrowOnCloseReader(new StringReader("s")), null)); // null consumer
326 
327         final IOConsumer<IOException> nullConsumer = null; // null consumer doesn't throw
328         assertDoesNotThrow(() -> IOUtils.close(nullCloseable, nullConsumer));
329         assertDoesNotThrow(() -> IOUtils.close(new StringReader("s"), nullConsumer));
330         assertDoesNotThrow(() -> IOUtils.close(new ThrowOnCloseReader(new StringReader("s")), nullConsumer));
331 
332         final IOConsumer<IOException> silentConsumer = IOConsumer.noop(); // noop consumer doesn't throw
333         assertDoesNotThrow(() -> IOUtils.close(nullCloseable, silentConsumer));
334         assertDoesNotThrow(() -> IOUtils.close(new StringReader("s"), silentConsumer));
335         assertDoesNotThrow(() -> IOUtils.close(new ThrowOnCloseReader(new StringReader("s")), silentConsumer));
336 
337         final IOConsumer<IOException> noisyConsumer = i -> {
338             throw i;
339         }; // consumer passes on the throw
340         assertDoesNotThrow(() -> IOUtils.close(nullCloseable, noisyConsumer)); // no throw
341         assertDoesNotThrow(() -> IOUtils.close(new StringReader("s"), noisyConsumer)); // no throw
342         assertThrows(IOException.class,
343             () -> IOUtils.close(new ThrowOnCloseReader(new StringReader("s")), noisyConsumer)); // closeable throws
344     }
345 
346     @Test
347     public void testCloseMulti() {
348         final Closeable nullCloseable = null;
349         final Closeable[] closeables = {null, null};
350         assertDoesNotThrow(() -> IOUtils.close(nullCloseable, nullCloseable));
351         assertDoesNotThrow(() -> IOUtils.close(closeables));
352         assertDoesNotThrow(() -> IOUtils.close((Closeable[]) null));
353         assertDoesNotThrow(() -> IOUtils.close(new StringReader("s"), nullCloseable));
354         assertThrows(IOException.class, () -> IOUtils.close(nullCloseable, new ThrowOnCloseReader(new StringReader("s"))));
355     }
356 
357     @Test
358     public void testCloseQuietly_AllCloseableIOException() {
359         final Closeable closeable = BrokenInputStream.INSTANCE;
360         assertDoesNotThrow(() -> IOUtils.closeQuietly(closeable, null, closeable));
361         assertDoesNotThrow(() -> IOUtils.closeQuietly(Arrays.asList(closeable, null, closeable)));
362         assertDoesNotThrow(() -> IOUtils.closeQuietly(Stream.of(closeable, null, closeable)));
363         assertDoesNotThrow(() -> IOUtils.closeQuietly((Iterable<Closeable>) null));
364     }
365 
366     @Test
367     public void testCloseQuietly_CloseableIOException() {
368         assertDoesNotThrow(() -> {
369             IOUtils.closeQuietly(BrokenInputStream.INSTANCE);
370         });
371         assertDoesNotThrow(() -> {
372             IOUtils.closeQuietly(BrokenOutputStream.INSTANCE);
373         });
374     }
375 
376     @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case"
377     @Test
378     public void testCloseQuietly_Selector() {
379         Selector selector = null;
380         try {
381             selector = Selector.open();
382         } catch (final IOException ignore) {
383         } finally {
384             IOUtils.closeQuietly(selector);
385         }
386     }
387 
388     @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case"
389     @Test
390     public void testCloseQuietly_SelectorIOException() {
391         final Selector selector = new SelectorAdapter() {
392             @Override
393             public void close() throws IOException {
394                 throw new IOException();
395             }
396         };
397         IOUtils.closeQuietly(selector);
398     }
399 
400     @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case"
401     @Test
402     public void testCloseQuietly_SelectorNull() {
403         final Selector selector = null;
404         IOUtils.closeQuietly(selector);
405     }
406 
407     @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case"
408     @Test
409     public void testCloseQuietly_SelectorTwice() {
410         Selector selector = null;
411         try {
412             selector = Selector.open();
413         } catch (final IOException ignore) {
414         } finally {
415             IOUtils.closeQuietly(selector);
416             IOUtils.closeQuietly(selector);
417         }
418     }
419 
420     @Test
421     public void testCloseQuietly_ServerSocket() {
422         assertDoesNotThrow(() -> IOUtils.closeQuietly((ServerSocket) null));
423         assertDoesNotThrow(() -> IOUtils.closeQuietly(new ServerSocket()));
424     }
425 
426     @Test
427     public void testCloseQuietly_ServerSocketIOException() {
428         assertDoesNotThrow(() -> {
429             IOUtils.closeQuietly(new ServerSocket() {
430                 @Override
431                 public void close() throws IOException {
432                     throw new IOException();
433                 }
434             });
435         });
436     }
437 
438     @Test
439     public void testCloseQuietly_Socket() {
440         assertDoesNotThrow(() -> IOUtils.closeQuietly((Socket) null));
441         assertDoesNotThrow(() -> IOUtils.closeQuietly(new Socket()));
442     }
443 
444     @Test
445     public void testCloseQuietly_SocketIOException() {
446         assertDoesNotThrow(() -> {
447             IOUtils.closeQuietly(new Socket() {
448                 @Override
449                 public synchronized void close() throws IOException {
450                     throw new IOException();
451                 }
452             });
453         });
454     }
455 
456     @Test
457     public void testCloseURLConnection() {
458         assertDoesNotThrow(() -> IOUtils.close((URLConnection) null));
459         assertDoesNotThrow(() -> IOUtils.close(new URL("https://www.apache.org/").openConnection()));
460         assertDoesNotThrow(() -> IOUtils.close(new URL("file:///").openConnection()));
461     }
462 
463     @Test
464     public void testConstants() {
465         assertEquals('/', IOUtils.DIR_SEPARATOR_UNIX);
466         assertEquals('\\', IOUtils.DIR_SEPARATOR_WINDOWS);
467         assertEquals("\n", IOUtils.LINE_SEPARATOR_UNIX);
468         assertEquals("\r\n", IOUtils.LINE_SEPARATOR_WINDOWS);
469         if (WINDOWS) {
470             assertEquals('\\', IOUtils.DIR_SEPARATOR);
471             assertEquals("\r\n", IOUtils.LINE_SEPARATOR);
472         } else {
473             assertEquals('/', IOUtils.DIR_SEPARATOR);
474             assertEquals("\n", IOUtils.LINE_SEPARATOR);
475         }
476         assertEquals('\r', IOUtils.CR);
477         assertEquals('\n', IOUtils.LF);
478         assertEquals(-1, IOUtils.EOF);
479     }
480 
481     @Test
482     public void testConsumeInputStream() throws Exception {
483         final long size = (long) Integer.MAX_VALUE + (long) 1;
484         final InputStream in = new NullInputStream(size);
485         final OutputStream out = NullOutputStream.INSTANCE;
486 
487         // Test copy() method
488         assertEquals(-1, IOUtils.copy(in, out));
489 
490         // reset the input
491         in.close();
492 
493         // Test consume() method
494         assertEquals(size, IOUtils.consume(in), "consume()");
495     }
496 
497     @Test
498     public void testConsumeReader() throws Exception {
499         final long size = (long) Integer.MAX_VALUE + (long) 1;
500         final Reader in = new NullReader(size);
501         final Writer out = NullWriter.INSTANCE;
502 
503         // Test copy() method
504         assertEquals(-1, IOUtils.copy(in, out));
505 
506         // reset the input
507         in.close();
508 
509         // Test consume() method
510         assertEquals(size, IOUtils.consume(in), "consume()");
511     }
512 
513     @Test
514     public void testContentEquals_InputStream_InputStream() throws Exception {
515         {
516             assertTrue(IOUtils.contentEquals((InputStream) null, null));
517         }
518         final byte[] dataEmpty = "".getBytes(StandardCharsets.UTF_8);
519         final byte[] dataAbc = "ABC".getBytes(StandardCharsets.UTF_8);
520         final byte[] dataAbcd = "ABCD".getBytes(StandardCharsets.UTF_8);
521         {
522             final ByteArrayInputStream input1 = new ByteArrayInputStream(dataEmpty);
523             assertFalse(IOUtils.contentEquals(input1, null));
524         }
525         {
526             final ByteArrayInputStream input1 = new ByteArrayInputStream(dataEmpty);
527             assertFalse(IOUtils.contentEquals(null, input1));
528         }
529         {
530             final ByteArrayInputStream input1 = new ByteArrayInputStream(dataEmpty);
531             assertTrue(IOUtils.contentEquals(input1, input1));
532         }
533         {
534             final ByteArrayInputStream input1 = new ByteArrayInputStream(dataAbc);
535             assertTrue(IOUtils.contentEquals(input1, input1));
536         }
537         assertTrue(IOUtils.contentEquals(new ByteArrayInputStream(dataEmpty), new ByteArrayInputStream(dataEmpty)));
538         assertTrue(IOUtils.contentEquals(new BufferedInputStream(new ByteArrayInputStream(dataEmpty)),
539             new BufferedInputStream(new ByteArrayInputStream(dataEmpty))));
540         assertTrue(IOUtils.contentEquals(new ByteArrayInputStream(dataAbc), new ByteArrayInputStream(dataAbc)));
541         assertFalse(IOUtils.contentEquals(new ByteArrayInputStream(dataAbcd), new ByteArrayInputStream(dataAbc)));
542         assertFalse(IOUtils.contentEquals(new ByteArrayInputStream(dataAbc), new ByteArrayInputStream(dataAbcd)));
543         assertFalse(IOUtils.contentEquals(new ByteArrayInputStream("apache".getBytes(StandardCharsets.UTF_8)),
544                 new ByteArrayInputStream("apacha".getBytes(StandardCharsets.UTF_8))));
545         // Tests with larger inputs that DEFAULT_BUFFER_SIZE in case internal buffers are used.
546         final byte[] bytes2XDefaultA = new byte[IOUtils.DEFAULT_BUFFER_SIZE * 2];
547         final byte[] bytes2XDefaultB = new byte[IOUtils.DEFAULT_BUFFER_SIZE * 2];
548         final byte[] bytes2XDefaultA2 = new byte[IOUtils.DEFAULT_BUFFER_SIZE * 2];
549         Arrays.fill(bytes2XDefaultA, (byte) 'a');
550         Arrays.fill(bytes2XDefaultB, (byte) 'b');
551         Arrays.fill(bytes2XDefaultA2, (byte) 'a');
552         bytes2XDefaultA2[bytes2XDefaultA2.length - 1] = 'd';
553         assertFalse(IOUtils.contentEquals(new ByteArrayInputStream(bytes2XDefaultA),
554             new ByteArrayInputStream(bytes2XDefaultB)));
555         assertFalse(IOUtils.contentEquals(new ByteArrayInputStream(bytes2XDefaultA),
556             new ByteArrayInputStream(bytes2XDefaultA2)));
557         assertTrue(IOUtils.contentEquals(new ByteArrayInputStream(bytes2XDefaultA),
558             new ByteArrayInputStream(bytes2XDefaultA)));
559         // FileInputStream a bit more than 16 k.
560         try (
561             final FileInputStream input1 = new FileInputStream(
562                 "src/test/resources/org/apache/commons/io/abitmorethan16k.txt");
563             final FileInputStream input2 = new FileInputStream(
564                 "src/test/resources/org/apache/commons/io/abitmorethan16kcopy.txt")) {
565             assertTrue(IOUtils.contentEquals(input1, input1));
566         }
567     }
568 
569     @Test
570     public void testContentEquals_Reader_Reader() throws Exception {
571         {
572             assertTrue(IOUtils.contentEquals((Reader) null, null));
573         }
574         {
575             final StringReader input1 = new StringReader("");
576             assertFalse(IOUtils.contentEquals(null, input1));
577         }
578         {
579             final StringReader input1 = new StringReader("");
580             assertFalse(IOUtils.contentEquals(input1, null));
581         }
582         {
583             final StringReader input1 = new StringReader("");
584             assertTrue(IOUtils.contentEquals(input1, input1));
585         }
586         {
587             final StringReader input1 = new StringReader("ABC");
588             assertTrue(IOUtils.contentEquals(input1, input1));
589         }
590         assertTrue(IOUtils.contentEquals(new StringReader(""), new StringReader("")));
591         assertTrue(
592             IOUtils.contentEquals(new BufferedReader(new StringReader("")), new BufferedReader(new StringReader(""))));
593         assertTrue(IOUtils.contentEquals(new StringReader("ABC"), new StringReader("ABC")));
594         assertFalse(IOUtils.contentEquals(new StringReader("ABCD"), new StringReader("ABC")));
595         assertFalse(IOUtils.contentEquals(new StringReader("ABC"), new StringReader("ABCD")));
596         assertFalse(IOUtils.contentEquals(new StringReader("apache"), new StringReader("apacha")));
597     }
598 
599     @Test
600     public void testContentEqualsIgnoreEOL() throws Exception {
601         {
602             assertTrue(IOUtils.contentEqualsIgnoreEOL(null, null));
603         }
604         final char[] empty = {};
605         {
606             final Reader input1 = new CharArrayReader(empty);
607             assertFalse(IOUtils.contentEqualsIgnoreEOL(null, input1));
608         }
609         {
610             final Reader input1 = new CharArrayReader(empty);
611             assertFalse(IOUtils.contentEqualsIgnoreEOL(input1, null));
612         }
613         {
614             final Reader input1 = new CharArrayReader(empty);
615             assertTrue(IOUtils.contentEqualsIgnoreEOL(input1, input1));
616         }
617         {
618             final Reader input1 = new CharArrayReader("321\r\n".toCharArray());
619             assertTrue(IOUtils.contentEqualsIgnoreEOL(input1, input1));
620         }
621 
622         testSingleEOL("", "", true);
623         testSingleEOL("", "\n", false);
624         testSingleEOL("", "\r", false);
625         testSingleEOL("", "\r\n", false);
626         testSingleEOL("", "\r\r", false);
627         testSingleEOL("", "\n\n", false);
628         testSingleEOL("1", "1", true);
629         testSingleEOL("1", "2", false);
630         testSingleEOL("123\rabc", "123\nabc", true);
631         testSingleEOL("321", "321\r\n", true);
632         testSingleEOL("321", "321\r\naabb", false);
633         testSingleEOL("321", "321\n", true);
634         testSingleEOL("321", "321\r", true);
635         testSingleEOL("321", "321\r\n", true);
636         testSingleEOL("321", "321\r\r", false);
637         testSingleEOL("321", "321\n\r", false);
638         testSingleEOL("321\n", "321", true);
639         testSingleEOL("321\n", "321\n\r", false);
640         testSingleEOL("321\n", "321\r\n", true);
641         testSingleEOL("321\r", "321\r\n", true);
642         testSingleEOL("321\r\n", "321\r\n\r", false);
643         testSingleEOL("123", "1234", false);
644         testSingleEOL("1235", "1234", false);
645     }
646 
647     @Test
648     public void testCopy_ByteArray_OutputStream() throws Exception {
649         final File destination = TestUtils.newFile(temporaryFolder, "copy8.txt");
650         final byte[] in;
651         try (InputStream fin = Files.newInputStream(testFilePath)) {
652             // Create our byte[]. Rely on testInputStreamToByteArray() to make sure this is valid.
653             in = IOUtils.toByteArray(fin);
654         }
655 
656         try (OutputStream fout = Files.newOutputStream(destination.toPath())) {
657             CopyUtils.copy(in, fout);
658 
659             fout.flush();
660 
661             TestUtils.checkFile(destination, testFile);
662             TestUtils.checkWrite(fout);
663         }
664         TestUtils.deleteFile(destination);
665     }
666 
667     @Test
668     public void testCopy_ByteArray_Writer() throws Exception {
669         final File destination = TestUtils.newFile(temporaryFolder, "copy7.txt");
670         final byte[] in;
671         try (InputStream fin = Files.newInputStream(testFilePath)) {
672             // Create our byte[]. Rely on testInputStreamToByteArray() to make sure this is valid.
673             in = IOUtils.toByteArray(fin);
674         }
675 
676         try (Writer fout = Files.newBufferedWriter(destination.toPath())) {
677             CopyUtils.copy(in, fout);
678             fout.flush();
679             TestUtils.checkFile(destination, testFile);
680             TestUtils.checkWrite(fout);
681         }
682         TestUtils.deleteFile(destination);
683     }
684 
685     @Test
686     public void testCopy_String_Writer() throws Exception {
687         final File destination = TestUtils.newFile(temporaryFolder, "copy6.txt");
688         final String str;
689         try (Reader fin = Files.newBufferedReader(testFilePath)) {
690             // Create our String. Rely on testReaderToString() to make sure this is valid.
691             str = IOUtils.toString(fin);
692         }
693 
694         try (Writer fout = Files.newBufferedWriter(destination.toPath())) {
695             CopyUtils.copy(str, fout);
696             fout.flush();
697 
698             TestUtils.checkFile(destination, testFile);
699             TestUtils.checkWrite(fout);
700         }
701         TestUtils.deleteFile(destination);
702     }
703 
704     @Test
705     public void testCopyLarge_CharExtraLength() throws IOException {
706         CharArrayReader is = null;
707         CharArrayWriter os = null;
708         try {
709             // Create streams
710             is = new CharArrayReader(carr);
711             os = new CharArrayWriter();
712 
713             // Test our copy method
714             // for extra length, it reads till EOF
715             assertEquals(200, IOUtils.copyLarge(is, os, 0, 2000));
716             final char[] oarr = os.toCharArray();
717 
718             // check that output length is correct
719             assertEquals(200, oarr.length);
720             // check that output data corresponds to input data
721             assertEquals(1, oarr[1]);
722             assertEquals(79, oarr[79]);
723             assertEquals((char) -1, oarr[80]);
724 
725         } finally {
726             IOUtils.closeQuietly(is);
727             IOUtils.closeQuietly(os);
728         }
729     }
730 
731     @Test
732     public void testCopyLarge_CharFullLength() throws IOException {
733         CharArrayReader is = null;
734         CharArrayWriter os = null;
735         try {
736             // Create streams
737             is = new CharArrayReader(carr);
738             os = new CharArrayWriter();
739 
740             // Test our copy method
741             assertEquals(200, IOUtils.copyLarge(is, os, 0, -1));
742             final char[] oarr = os.toCharArray();
743 
744             // check that output length is correct
745             assertEquals(200, oarr.length);
746             // check that output data corresponds to input data
747             assertEquals(1, oarr[1]);
748             assertEquals(79, oarr[79]);
749             assertEquals((char) -1, oarr[80]);
750 
751         } finally {
752             IOUtils.closeQuietly(is);
753             IOUtils.closeQuietly(os);
754         }
755     }
756 
757     @Test
758     public void testCopyLarge_CharNoSkip() throws IOException {
759         CharArrayReader is = null;
760         CharArrayWriter os = null;
761         try {
762             // Create streams
763             is = new CharArrayReader(carr);
764             os = new CharArrayWriter();
765 
766             // Test our copy method
767             assertEquals(100, IOUtils.copyLarge(is, os, 0, 100));
768             final char[] oarr = os.toCharArray();
769 
770             // check that output length is correct
771             assertEquals(100, oarr.length);
772             // check that output data corresponds to input data
773             assertEquals(1, oarr[1]);
774             assertEquals(79, oarr[79]);
775             assertEquals((char) -1, oarr[80]);
776 
777         } finally {
778             IOUtils.closeQuietly(is);
779             IOUtils.closeQuietly(os);
780         }
781     }
782 
783     @Test
784     public void testCopyLarge_CharSkip() throws IOException {
785         CharArrayReader is = null;
786         CharArrayWriter os = null;
787         try {
788             // Create streams
789             is = new CharArrayReader(carr);
790             os = new CharArrayWriter();
791 
792             // Test our copy method
793             assertEquals(100, IOUtils.copyLarge(is, os, 10, 100));
794             final char[] oarr = os.toCharArray();
795 
796             // check that output length is correct
797             assertEquals(100, oarr.length);
798             // check that output data corresponds to input data
799             assertEquals(11, oarr[1]);
800             assertEquals(79, oarr[69]);
801             assertEquals((char) -1, oarr[70]);
802 
803         } finally {
804             IOUtils.closeQuietly(is);
805             IOUtils.closeQuietly(os);
806         }
807     }
808 
809     @Test
810     public void testCopyLarge_CharSkipInvalid() {
811         try (CharArrayReader is = new CharArrayReader(carr); CharArrayWriter os = new CharArrayWriter()) {
812             assertThrows(EOFException.class, () -> IOUtils.copyLarge(is, os, 1000, 100));
813         }
814     }
815 
816     @Test
817     public void testCopyLarge_ExtraLength() throws IOException {
818         try (ByteArrayInputStream is = new ByteArrayInputStream(iarr);
819             ByteArrayOutputStream os = new ByteArrayOutputStream()) {
820             // Create streams
821 
822             // Test our copy method
823             // for extra length, it reads till EOF
824             assertEquals(200, IOUtils.copyLarge(is, os, 0, 2000));
825             final byte[] oarr = os.toByteArray();
826 
827             // check that output length is correct
828             assertEquals(200, oarr.length);
829             // check that output data corresponds to input data
830             assertEquals(1, oarr[1]);
831             assertEquals(79, oarr[79]);
832             assertEquals(-1, oarr[80]);
833         }
834     }
835 
836     @Test
837     public void testCopyLarge_FullLength() throws IOException {
838         try (ByteArrayInputStream is = new ByteArrayInputStream(iarr);
839             ByteArrayOutputStream os = new ByteArrayOutputStream()) {
840             // Test our copy method
841             assertEquals(200, IOUtils.copyLarge(is, os, 0, -1));
842             final byte[] oarr = os.toByteArray();
843 
844             // check that output length is correct
845             assertEquals(200, oarr.length);
846             // check that output data corresponds to input data
847             assertEquals(1, oarr[1]);
848             assertEquals(79, oarr[79]);
849             assertEquals(-1, oarr[80]);
850         }
851     }
852 
853     @Test
854     public void testCopyLarge_NoSkip() throws IOException {
855         try (ByteArrayInputStream is = new ByteArrayInputStream(iarr);
856             ByteArrayOutputStream os = new ByteArrayOutputStream()) {
857             // Test our copy method
858             assertEquals(100, IOUtils.copyLarge(is, os, 0, 100));
859             final byte[] oarr = os.toByteArray();
860 
861             // check that output length is correct
862             assertEquals(100, oarr.length);
863             // check that output data corresponds to input data
864             assertEquals(1, oarr[1]);
865             assertEquals(79, oarr[79]);
866             assertEquals(-1, oarr[80]);
867         }
868     }
869 
870     @Test
871     public void testCopyLarge_Skip() throws IOException {
872         try (ByteArrayInputStream is = new ByteArrayInputStream(iarr);
873             ByteArrayOutputStream os = new ByteArrayOutputStream()) {
874             // Test our copy method
875             assertEquals(100, IOUtils.copyLarge(is, os, 10, 100));
876             final byte[] oarr = os.toByteArray();
877 
878             // check that output length is correct
879             assertEquals(100, oarr.length);
880             // check that output data corresponds to input data
881             assertEquals(11, oarr[1]);
882             assertEquals(79, oarr[69]);
883             assertEquals(-1, oarr[70]);
884         }
885     }
886 
887     @Test
888     public void testCopyLarge_SkipInvalid() throws IOException {
889         try (ByteArrayInputStream is = new ByteArrayInputStream(iarr);
890             ByteArrayOutputStream os = new ByteArrayOutputStream()) {
891             // Test our copy method
892             assertThrows(EOFException.class, () -> IOUtils.copyLarge(is, os, 1000, 100));
893         }
894     }
895 
896     @Test
897     public void testCopyLarge_SkipWithInvalidOffset() throws IOException {
898         ByteArrayInputStream is = null;
899         ByteArrayOutputStream os = null;
900         try {
901             // Create streams
902             is = new ByteArrayInputStream(iarr);
903             os = new ByteArrayOutputStream();
904 
905             // Test our copy method
906             assertEquals(100, IOUtils.copyLarge(is, os, -10, 100));
907             final byte[] oarr = os.toByteArray();
908 
909             // check that output length is correct
910             assertEquals(100, oarr.length);
911             // check that output data corresponds to input data
912             assertEquals(1, oarr[1]);
913             assertEquals(79, oarr[79]);
914             assertEquals(-1, oarr[80]);
915 
916         } finally {
917             IOUtils.closeQuietly(is);
918             IOUtils.closeQuietly(os);
919         }
920     }
921 
922     @Test
923     public void testRead_ReadableByteChannel() throws Exception {
924         final ByteBuffer buffer = ByteBuffer.allocate(FILE_SIZE);
925         final FileInputStream fileInputStream = new FileInputStream(testFile);
926         final FileChannel input = fileInputStream.getChannel();
927         try {
928             assertEquals(FILE_SIZE, IOUtils.read(input, buffer));
929             assertEquals(0, IOUtils.read(input, buffer));
930             assertEquals(0, buffer.remaining());
931             assertEquals(0, input.read(buffer));
932             buffer.clear();
933             assertThrows(EOFException.class, () -> IOUtils.readFully(input, buffer), "Should have failed with EOFException");
934         } finally {
935             IOUtils.closeQuietly(input, fileInputStream);
936         }
937     }
938 
939     @Test
940     public void testReadFully_InputStream__ReturnByteArray() throws Exception {
941         final byte[] bytes = "abcd1234".getBytes(StandardCharsets.UTF_8);
942         final ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
943 
944         final byte[] result = IOUtils.readFully(stream, bytes.length);
945 
946         IOUtils.closeQuietly(stream);
947 
948         assertEqualContent(result, bytes);
949     }
950 
951     @Test
952     public void testReadFully_InputStream_ByteArray() throws Exception {
953         final int size = 1027;
954         final byte[] buffer = new byte[size];
955         final InputStream input = new ByteArrayInputStream(new byte[size]);
956 
957         assertThrows(IllegalArgumentException.class, () -> IOUtils.readFully(input, buffer, 0, -1), "Should have failed with IllegalArgumentException");
958 
959         IOUtils.readFully(input, buffer, 0, 0);
960         IOUtils.readFully(input, buffer, 0, size - 1);
961         assertThrows(EOFException.class, () -> IOUtils.readFully(input, buffer, 0, 2), "Should have failed with EOFException");
962         IOUtils.closeQuietly(input);
963     }
964 
965     @Test
966     public void testReadFully_InputStream_Offset() throws Exception {
967         final InputStream stream = CharSequenceInputStream.builder().setCharSequence("abcd1234").setCharset(StandardCharsets.UTF_8).get();
968         final byte[] buffer = "wx00000000".getBytes(StandardCharsets.UTF_8);
969         IOUtils.readFully(stream, buffer, 2, 8);
970         assertEquals("wxabcd1234", new String(buffer, 0, buffer.length, StandardCharsets.UTF_8));
971         IOUtils.closeQuietly(stream);
972     }
973 
974     @Test
975     public void testReadFully_ReadableByteChannel() throws Exception {
976         final ByteBuffer buffer = ByteBuffer.allocate(FILE_SIZE);
977         final FileInputStream fileInputStream = new FileInputStream(testFile);
978         final FileChannel input = fileInputStream.getChannel();
979         try {
980             IOUtils.readFully(input, buffer);
981             assertEquals(FILE_SIZE, buffer.position());
982             assertEquals(0, buffer.remaining());
983             assertEquals(0, input.read(buffer));
984             IOUtils.readFully(input, buffer);
985             assertEquals(FILE_SIZE, buffer.position());
986             assertEquals(0, buffer.remaining());
987             assertEquals(0, input.read(buffer));
988             IOUtils.readFully(input, buffer);
989             buffer.clear();
990             assertThrows(EOFException.class, () -> IOUtils.readFully(input, buffer), "Should have failed with EOFxception");
991         } finally {
992             IOUtils.closeQuietly(input, fileInputStream);
993         }
994     }
995 
996     @Test
997     public void testReadFully_Reader() throws Exception {
998         final int size = 1027;
999         final char[] buffer = new char[size];
1000         final Reader input = new CharArrayReader(new char[size]);
1001 
1002         IOUtils.readFully(input, buffer, 0, 0);
1003         IOUtils.readFully(input, buffer, 0, size - 3);
1004         assertThrows(IllegalArgumentException.class, () -> IOUtils.readFully(input, buffer, 0, -1), "Should have failed with IllegalArgumentException");
1005         assertThrows(EOFException.class, () -> IOUtils.readFully(input, buffer, 0, 5), "Should have failed with EOFException");
1006         IOUtils.closeQuietly(input);
1007     }
1008 
1009     @Test
1010     public void testReadFully_Reader_Offset() throws Exception {
1011         final Reader reader = new StringReader("abcd1234");
1012         final char[] buffer = "wx00000000".toCharArray();
1013         IOUtils.readFully(reader, buffer, 2, 8);
1014         assertEquals("wxabcd1234", new String(buffer));
1015         IOUtils.closeQuietly(reader);
1016     }
1017 
1018     @Test
1019     public void testReadLines_InputStream() throws Exception {
1020         final File file = TestUtils.newFile(temporaryFolder, "lines.txt");
1021         InputStream in = null;
1022         try {
1023             final String[] data = {"hello", "world", "", "this is", "some text"};
1024             TestUtils.createLineBasedFile(file, data);
1025 
1026             in = Files.newInputStream(file.toPath());
1027             final List<String> lines = IOUtils.readLines(in);
1028             assertEquals(Arrays.asList(data), lines);
1029             assertEquals(-1, in.read());
1030         } finally {
1031             IOUtils.closeQuietly(in);
1032             TestUtils.deleteFile(file);
1033         }
1034     }
1035 
1036     @Test
1037     public void testReadLines_InputStream_String() throws Exception {
1038         final File file = TestUtils.newFile(temporaryFolder, "lines.txt");
1039         InputStream in = null;
1040         try {
1041             final String[] data = {"hello", "/u1234", "", "this is", "some text"};
1042             TestUtils.createLineBasedFile(file, data);
1043 
1044             in = Files.newInputStream(file.toPath());
1045             final List<String> lines = IOUtils.readLines(in, UTF_8);
1046             assertEquals(Arrays.asList(data), lines);
1047             assertEquals(-1, in.read());
1048         } finally {
1049             IOUtils.closeQuietly(in);
1050             TestUtils.deleteFile(file);
1051         }
1052     }
1053 
1054     @Test
1055     public void testReadLines_Reader() throws Exception {
1056         final File file = TestUtils.newFile(temporaryFolder, "lines.txt");
1057         Reader in = null;
1058         try {
1059             final String[] data = {"hello", "/u1234", "", "this is", "some text"};
1060             TestUtils.createLineBasedFile(file, data);
1061 
1062             in = new InputStreamReader(Files.newInputStream(file.toPath()));
1063             final List<String> lines = IOUtils.readLines(in);
1064             assertEquals(Arrays.asList(data), lines);
1065             assertEquals(-1, in.read());
1066         } finally {
1067             IOUtils.closeQuietly(in);
1068             TestUtils.deleteFile(file);
1069         }
1070     }
1071 
1072     @Test
1073     public void testResourceToByteArray_ExistingResourceAtRootPackage() throws Exception {
1074         final long fileSize = TestResources.getFile("test-file-utf8.bin").length();
1075         final byte[] bytes = IOUtils.resourceToByteArray("/org/apache/commons/io/test-file-utf8.bin");
1076         assertNotNull(bytes);
1077         assertEquals(fileSize, bytes.length);
1078     }
1079 
1080     @Test
1081     public void testResourceToByteArray_ExistingResourceAtRootPackage_WithClassLoader() throws Exception {
1082         final long fileSize = TestResources.getFile("test-file-utf8.bin").length();
1083         final byte[] bytes = IOUtils.resourceToByteArray("org/apache/commons/io/test-file-utf8.bin",
1084             ClassLoader.getSystemClassLoader());
1085         assertNotNull(bytes);
1086         assertEquals(fileSize, bytes.length);
1087     }
1088 
1089     @Test
1090     public void testResourceToByteArray_ExistingResourceAtSubPackage() throws Exception {
1091         final long fileSize = TestResources.getFile("FileUtilsTestDataCR.dat").length();
1092         final byte[] bytes = IOUtils.resourceToByteArray("/org/apache/commons/io/FileUtilsTestDataCR.dat");
1093         assertNotNull(bytes);
1094         assertEquals(fileSize, bytes.length);
1095     }
1096 
1097     @Test
1098     public void testResourceToByteArray_ExistingResourceAtSubPackage_WithClassLoader() throws Exception {
1099         final long fileSize = TestResources.getFile("FileUtilsTestDataCR.dat").length();
1100         final byte[] bytes = IOUtils.resourceToByteArray("org/apache/commons/io/FileUtilsTestDataCR.dat",
1101             ClassLoader.getSystemClassLoader());
1102         assertNotNull(bytes);
1103         assertEquals(fileSize, bytes.length);
1104     }
1105 
1106     @Test
1107     public void testResourceToByteArray_NonExistingResource() {
1108         assertThrows(IOException.class, () -> IOUtils.resourceToByteArray("/non-existing-file.bin"));
1109     }
1110 
1111     @Test
1112     public void testResourceToByteArray_NonExistingResource_WithClassLoader() {
1113         assertThrows(IOException.class,
1114             () -> IOUtils.resourceToByteArray("non-existing-file.bin", ClassLoader.getSystemClassLoader()));
1115     }
1116 
1117     @Test
1118     public void testResourceToByteArray_Null() {
1119         assertThrows(NullPointerException.class, () -> IOUtils.resourceToByteArray(null));
1120     }
1121 
1122     @Test
1123     public void testResourceToByteArray_Null_WithClassLoader() {
1124         assertThrows(NullPointerException.class,
1125             () -> IOUtils.resourceToByteArray(null, ClassLoader.getSystemClassLoader()));
1126     }
1127 
1128     @Test
1129     public void testResourceToString_ExistingResourceAtRootPackage() throws Exception {
1130         final long fileSize = TestResources.getFile("test-file-simple-utf8.bin").length();
1131         final String content = IOUtils.resourceToString("/org/apache/commons/io/test-file-simple-utf8.bin",
1132             StandardCharsets.UTF_8);
1133 
1134         assertNotNull(content);
1135         assertEquals(fileSize, content.getBytes().length);
1136     }
1137 
1138     @Test
1139     public void testResourceToString_ExistingResourceAtRootPackage_WithClassLoader() throws Exception {
1140         final long fileSize = TestResources.getFile("test-file-simple-utf8.bin").length();
1141         final String content = IOUtils.resourceToString("org/apache/commons/io/test-file-simple-utf8.bin",
1142             StandardCharsets.UTF_8, ClassLoader.getSystemClassLoader());
1143 
1144         assertNotNull(content);
1145         assertEquals(fileSize, content.getBytes().length);
1146     }
1147 
1148     @Test
1149     public void testResourceToString_ExistingResourceAtSubPackage() throws Exception {
1150         final long fileSize = TestResources.getFile("FileUtilsTestDataCR.dat").length();
1151         final String content = IOUtils.resourceToString("/org/apache/commons/io/FileUtilsTestDataCR.dat",
1152             StandardCharsets.UTF_8);
1153 
1154         assertNotNull(content);
1155         assertEquals(fileSize, content.getBytes().length);
1156     }
1157 
1158     // Tests from IO-305
1159 
1160     @Test
1161     public void testResourceToString_ExistingResourceAtSubPackage_WithClassLoader() throws Exception {
1162         final long fileSize = TestResources.getFile("FileUtilsTestDataCR.dat").length();
1163         final String content = IOUtils.resourceToString("org/apache/commons/io/FileUtilsTestDataCR.dat",
1164             StandardCharsets.UTF_8, ClassLoader.getSystemClassLoader());
1165 
1166         assertNotNull(content);
1167         assertEquals(fileSize, content.getBytes().length);
1168     }
1169 
1170     @Test
1171     public void testResourceToString_NonExistingResource() {
1172         assertThrows(IOException.class,
1173             () -> IOUtils.resourceToString("/non-existing-file.bin", StandardCharsets.UTF_8));
1174     }
1175 
1176     @Test
1177     public void testResourceToString_NonExistingResource_WithClassLoader() {
1178         assertThrows(IOException.class, () -> IOUtils.resourceToString("non-existing-file.bin", StandardCharsets.UTF_8,
1179             ClassLoader.getSystemClassLoader()));
1180     }
1181 
1182     @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case"
1183     @Test
1184     public void testResourceToString_NullCharset() throws Exception {
1185         IOUtils.resourceToString("/org/apache/commons/io//test-file-utf8.bin", null);
1186     }
1187 
1188     @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case"
1189     @Test
1190     public void testResourceToString_NullCharset_WithClassLoader() throws Exception {
1191         IOUtils.resourceToString("org/apache/commons/io/test-file-utf8.bin", null, ClassLoader.getSystemClassLoader());
1192     }
1193 
1194     @Test
1195     public void testResourceToString_NullResource() {
1196         assertThrows(NullPointerException.class, () -> IOUtils.resourceToString(null, StandardCharsets.UTF_8));
1197     }
1198 
1199     @Test
1200     public void testResourceToString_NullResource_WithClassLoader() {
1201         assertThrows(NullPointerException.class,
1202             () -> IOUtils.resourceToString(null, StandardCharsets.UTF_8, ClassLoader.getSystemClassLoader()));
1203     }
1204 
1205     @Test
1206     public void testResourceToURL_ExistingResourceAtRootPackage() throws Exception {
1207         final URL url = IOUtils.resourceToURL("/org/apache/commons/io/test-file-utf8.bin");
1208         assertNotNull(url);
1209         assertTrue(url.getFile().endsWith("/test-file-utf8.bin"));
1210     }
1211 
1212     @Test
1213     public void testResourceToURL_ExistingResourceAtRootPackage_WithClassLoader() throws Exception {
1214         final URL url = IOUtils.resourceToURL("org/apache/commons/io/test-file-utf8.bin",
1215             ClassLoader.getSystemClassLoader());
1216         assertNotNull(url);
1217         assertTrue(url.getFile().endsWith("/org/apache/commons/io/test-file-utf8.bin"));
1218     }
1219 
1220     @Test
1221     public void testResourceToURL_ExistingResourceAtSubPackage() throws Exception {
1222         final URL url = IOUtils.resourceToURL("/org/apache/commons/io/FileUtilsTestDataCR.dat");
1223         assertNotNull(url);
1224         assertTrue(url.getFile().endsWith("/org/apache/commons/io/FileUtilsTestDataCR.dat"));
1225     }
1226 
1227     @Test
1228     public void testResourceToURL_ExistingResourceAtSubPackage_WithClassLoader() throws Exception {
1229         final URL url = IOUtils.resourceToURL("org/apache/commons/io/FileUtilsTestDataCR.dat",
1230             ClassLoader.getSystemClassLoader());
1231 
1232         assertNotNull(url);
1233         assertTrue(url.getFile().endsWith("/org/apache/commons/io/FileUtilsTestDataCR.dat"));
1234     }
1235 
1236     @Test
1237     public void testResourceToURL_NonExistingResource() {
1238         assertThrows(IOException.class, () -> IOUtils.resourceToURL("/non-existing-file.bin"));
1239     }
1240 
1241     @Test
1242     public void testResourceToURL_NonExistingResource_WithClassLoader() {
1243         assertThrows(IOException.class,
1244             () -> IOUtils.resourceToURL("non-existing-file.bin", ClassLoader.getSystemClassLoader()));
1245     }
1246 
1247     @Test
1248     public void testResourceToURL_Null() {
1249         assertThrows(NullPointerException.class, () -> IOUtils.resourceToURL(null));
1250     }
1251 
1252     @Test
1253     public void testResourceToURL_Null_WithClassLoader() {
1254         assertThrows(NullPointerException.class, () -> IOUtils.resourceToURL(null, ClassLoader.getSystemClassLoader()));
1255     }
1256 
1257     public void testSingleEOL(final String s1, final String s2, final boolean ifEquals) {
1258         assertEquals(ifEquals, IOUtils.contentEqualsIgnoreEOL(
1259                 new CharArrayReader(s1.toCharArray()),
1260                 new CharArrayReader(s2.toCharArray())
1261         ), "failed at :{" + s1 + "," + s2 + "}");
1262         assertEquals(ifEquals, IOUtils.contentEqualsIgnoreEOL(
1263                 new CharArrayReader(s2.toCharArray()),
1264                 new CharArrayReader(s1.toCharArray())
1265         ), "failed at :{" + s2 + "," + s1 + "}");
1266         assertTrue(IOUtils.contentEqualsIgnoreEOL(
1267                 new CharArrayReader(s1.toCharArray()),
1268                 new CharArrayReader(s1.toCharArray())
1269         ), "failed at :{" + s1 + "," + s1 + "}");
1270         assertTrue(IOUtils.contentEqualsIgnoreEOL(
1271                 new CharArrayReader(s2.toCharArray()),
1272                 new CharArrayReader(s2.toCharArray())
1273         ), "failed at :{" + s2 + "," + s2 + "}");
1274     }
1275 
1276     @Test
1277     public void testSkip_FileReader() throws Exception {
1278         try (Reader in = Files.newBufferedReader(testFilePath)) {
1279             assertEquals(FILE_SIZE - 10, IOUtils.skip(in, FILE_SIZE - 10));
1280             assertEquals(10, IOUtils.skip(in, 20));
1281             assertEquals(0, IOUtils.skip(in, 10));
1282         }
1283     }
1284 
1285     @Test
1286     public void testSkip_InputStream() throws Exception {
1287         try (InputStream in = Files.newInputStream(testFilePath)) {
1288             assertEquals(FILE_SIZE - 10, IOUtils.skip(in, FILE_SIZE - 10));
1289             assertEquals(10, IOUtils.skip(in, 20));
1290             assertEquals(0, IOUtils.skip(in, 10));
1291         }
1292     }
1293 
1294     @Test
1295     public void testSkip_ReadableByteChannel() throws Exception {
1296         final FileInputStream fileInputStream = new FileInputStream(testFile);
1297         final FileChannel fileChannel = fileInputStream.getChannel();
1298         try {
1299             assertEquals(FILE_SIZE - 10, IOUtils.skip(fileChannel, FILE_SIZE - 10));
1300             assertEquals(10, IOUtils.skip(fileChannel, 20));
1301             assertEquals(0, IOUtils.skip(fileChannel, 10));
1302         } finally {
1303             IOUtils.closeQuietly(fileChannel, fileInputStream);
1304         }
1305     }
1306 
1307     @Test
1308     public void testSkipFully_InputStream() throws Exception {
1309         final int size = 1027;
1310 
1311         try (final InputStream input = new ByteArrayInputStream(new byte[size])) {
1312             assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1), "Should have failed with IllegalArgumentException");
1313 
1314             IOUtils.skipFully(input, 0);
1315             IOUtils.skipFully(input, size - 1);
1316             assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2), "Should have failed with IOException");
1317         }
1318     }
1319 
1320     @Test
1321     public void testSkipFully_InputStream_Buffer_New_bytes() throws Exception {
1322         final int size = 1027;
1323         final Supplier<byte[]> bas = () -> new byte[size];
1324         try (final InputStream input = new ByteArrayInputStream(new byte[size])) {
1325             assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1, bas), "Should have failed with IllegalArgumentException");
1326 
1327             IOUtils.skipFully(input, 0, bas);
1328             IOUtils.skipFully(input, size - 1, bas);
1329             assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2, bas), "Should have failed with IOException");
1330         }
1331     }
1332 
1333     @Test
1334     public void testSkipFully_InputStream_Buffer_Reuse_bytes() throws Exception {
1335         final int size = 1027;
1336         final byte[] ba = new byte[size];
1337         final Supplier<byte[]> bas = () -> ba;
1338         try (final InputStream input = new ByteArrayInputStream(new byte[size])) {
1339             assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1, bas), "Should have failed with IllegalArgumentException");
1340 
1341             IOUtils.skipFully(input, 0, bas);
1342             IOUtils.skipFully(input, size - 1, bas);
1343             assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2, bas), "Should have failed with IOException");
1344         }
1345     }
1346 
1347     @Test
1348     public void testSkipFully_InputStream_Buffer_Reuse_ThreadLocal() throws Exception {
1349         final int size = 1027;
1350         final ThreadLocal<byte[]> tl = ThreadLocal.withInitial(() -> new byte[size]);
1351         try (final InputStream input = new ByteArrayInputStream(new byte[size])) {
1352             assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1, tl::get), "Should have failed with IllegalArgumentException");
1353 
1354             IOUtils.skipFully(input, 0, tl::get);
1355             IOUtils.skipFully(input, size - 1, tl::get);
1356             assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2, tl::get), "Should have failed with IOException");
1357         }
1358     }
1359 
1360     @Test
1361     public void testSkipFully_ReadableByteChannel() throws Exception {
1362         final FileInputStream fileInputStream = new FileInputStream(testFile);
1363         final FileChannel fileChannel = fileInputStream.getChannel();
1364         try {
1365             assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(fileChannel, -1), "Should have failed with IllegalArgumentException");
1366             IOUtils.skipFully(fileChannel, 0);
1367             IOUtils.skipFully(fileChannel, FILE_SIZE - 1);
1368             assertThrows(IOException.class, () -> IOUtils.skipFully(fileChannel, 2), "Should have failed with IOException");
1369         } finally {
1370             IOUtils.closeQuietly(fileChannel, fileInputStream);
1371         }
1372     }
1373 
1374     @Test
1375     public void testSkipFully_Reader() throws Exception {
1376         final int size = 1027;
1377         try (final Reader input = new CharArrayReader(new char[size])) {
1378             IOUtils.skipFully(input, 0);
1379             IOUtils.skipFully(input, size - 3);
1380             assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1), "Should have failed with IllegalArgumentException");
1381             assertThrows(IOException.class, () -> IOUtils.skipFully(input, 5), "Should have failed with IOException");
1382         }
1383     }
1384 
1385     @Test
1386     public void testStringToOutputStream() throws Exception {
1387         final File destination = TestUtils.newFile(temporaryFolder, "copy5.txt");
1388         final String str;
1389         try (Reader fin = Files.newBufferedReader(testFilePath)) {
1390             // Create our String. Rely on testReaderToString() to make sure this is valid.
1391             str = IOUtils.toString(fin);
1392         }
1393 
1394         try (OutputStream fout = Files.newOutputStream(destination.toPath())) {
1395             CopyUtils.copy(str, fout);
1396             // Note: this method *does* flush. It is equivalent to:
1397             // OutputStreamWriter _out = new OutputStreamWriter(fout);
1398             // CopyUtils.copy( str, _out, 4096 ); // copy( Reader, Writer, int );
1399             // _out.flush();
1400             // out = fout;
1401             // note: we don't flush here; this IOUtils method does it for us
1402 
1403             TestUtils.checkFile(destination, testFile);
1404             TestUtils.checkWrite(fout);
1405         }
1406         TestUtils.deleteFile(destination);
1407     }
1408 
1409     @Test
1410     public void testToBufferedInputStream_InputStream() throws Exception {
1411         try (InputStream fin = Files.newInputStream(testFilePath)) {
1412             final InputStream in = IOUtils.toBufferedInputStream(fin);
1413             final byte[] out = IOUtils.toByteArray(in);
1414             assertNotNull(out);
1415             assertEquals(0, fin.available(), "Not all bytes were read");
1416             assertEquals(FILE_SIZE, out.length, "Wrong output size");
1417             TestUtils.assertEqualContent(out, testFile);
1418         }
1419     }
1420 
1421     @Test
1422     public void testToBufferedInputStreamWithBufferSize_InputStream() throws Exception {
1423         try (InputStream fin = Files.newInputStream(testFilePath)) {
1424             final InputStream in = IOUtils.toBufferedInputStream(fin, 2048);
1425             final byte[] out = IOUtils.toByteArray(in);
1426             assertNotNull(out);
1427             assertEquals(0, fin.available(), "Not all bytes were read");
1428             assertEquals(FILE_SIZE, out.length, "Wrong output size");
1429             TestUtils.assertEqualContent(out, testFile);
1430         }
1431     }
1432 
1433     @Test
1434     public void testToByteArray_InputStream() throws Exception {
1435         try (InputStream fin = Files.newInputStream(testFilePath)) {
1436             final byte[] out = IOUtils.toByteArray(fin);
1437             assertNotNull(out);
1438             assertEquals(0, fin.available(), "Not all bytes were read");
1439             assertEquals(FILE_SIZE, out.length, "Wrong output size");
1440             TestUtils.assertEqualContent(out, testFile);
1441         }
1442     }
1443 
1444     @Test
1445     @Disabled("Disable by default as it uses too much memory and can cause builds to fail.")
1446     public void testToByteArray_InputStream_LongerThanIntegerMaxValue() throws Exception {
1447         final CircularInputStream cin = new CircularInputStream(IOUtils.byteArray(), Integer.MAX_VALUE + 1L);
1448         assertThrows(IllegalArgumentException.class, () -> IOUtils.toByteArray(cin));
1449     }
1450 
1451     @Test
1452     public void testToByteArray_InputStream_NegativeSize() throws Exception {
1453         try (InputStream fin = Files.newInputStream(testFilePath)) {
1454             final IllegalArgumentException exc = assertThrows(IllegalArgumentException.class, () -> IOUtils.toByteArray(fin, -1),
1455                     "Should have failed with IllegalArgumentException");
1456             assertTrue(exc.getMessage().startsWith("Size must be equal or greater than zero"),
1457                     "Exception message does not start with \"Size must be equal or greater than zero\"");
1458         }
1459     }
1460 
1461     @Test
1462     public void testToByteArray_InputStream_Size() throws Exception {
1463         try (InputStream fin = Files.newInputStream(testFilePath)) {
1464             final byte[] out = IOUtils.toByteArray(fin, testFile.length());
1465             assertNotNull(out);
1466             assertEquals(0, fin.available(), "Not all bytes were read");
1467             assertEquals(FILE_SIZE, out.length, "Wrong output size: out.length=" + out.length + "!=" + FILE_SIZE);
1468             TestUtils.assertEqualContent(out, testFile);
1469         }
1470     }
1471 
1472     @Test
1473     public void testToByteArray_InputStream_SizeIllegal() throws Exception {
1474         try (InputStream fin = Files.newInputStream(testFilePath)) {
1475             final IOException exc = assertThrows(IOException.class, () -> IOUtils.toByteArray(fin, testFile.length() + 1),
1476                     "Should have failed with IOException");
1477             assertTrue(exc.getMessage().startsWith("Unexpected read size"), "Exception message does not start with \"Unexpected read size\"");
1478         }
1479     }
1480 
1481     @Test
1482     public void testToByteArray_InputStream_SizeLong() throws Exception {
1483         try (InputStream fin = Files.newInputStream(testFilePath)) {
1484             final IllegalArgumentException exc = assertThrows(IllegalArgumentException.class, () -> IOUtils.toByteArray(fin, (long) Integer.MAX_VALUE + 1),
1485                     "Should have failed with IllegalArgumentException");
1486             assertTrue(exc.getMessage().startsWith("Size cannot be greater than Integer max value"),
1487                     "Exception message does not start with \"Size cannot be greater than Integer max value\"");
1488         }
1489     }
1490 
1491     @Test
1492     public void testToByteArray_InputStream_SizeOne() throws Exception {
1493         try (InputStream fin = Files.newInputStream(testFilePath)) {
1494             final byte[] out = IOUtils.toByteArray(fin, 1);
1495             assertNotNull(out, "Out cannot be null");
1496             assertEquals(1, out.length, "Out length must be 1");
1497         }
1498     }
1499 
1500     @Test
1501     public void testToByteArray_InputStream_SizeZero() throws Exception {
1502         try (InputStream fin =Files.newInputStream(testFilePath)) {
1503             final byte[] out = IOUtils.toByteArray(fin, 0);
1504             assertNotNull(out, "Out cannot be null");
1505             assertEquals(0, out.length, "Out length must be 0");
1506         }
1507     }
1508 
1509     @Test
1510     public void testToByteArray_Reader() throws IOException {
1511         final String charsetName = UTF_8;
1512         final byte[] expected = charsetName.getBytes(charsetName);
1513         byte[] actual = IOUtils.toByteArray(new InputStreamReader(new ByteArrayInputStream(expected)));
1514         assertArrayEquals(expected, actual);
1515         actual = IOUtils.toByteArray(new InputStreamReader(new ByteArrayInputStream(expected)), charsetName);
1516         assertArrayEquals(expected, actual);
1517     }
1518 
1519     @Test
1520     public void testToByteArray_String() throws Exception {
1521         try (Reader fin = Files.newBufferedReader(testFilePath)) {
1522             // Create our String. Rely on testReaderToString() to make sure this is valid.
1523             final String str = IOUtils.toString(fin);
1524 
1525             final byte[] out = IOUtils.toByteArray(str);
1526             assertEqualContent(str.getBytes(), out);
1527         }
1528     }
1529 
1530     @Test
1531     public void testToByteArray_URI() throws Exception {
1532         final URI url = testFile.toURI();
1533         final byte[] actual = IOUtils.toByteArray(url);
1534         assertEquals(FILE_SIZE, actual.length);
1535     }
1536 
1537     @Test
1538     public void testToByteArray_URL() throws Exception {
1539         final URL url = testFile.toURI().toURL();
1540         final byte[] actual = IOUtils.toByteArray(url);
1541         assertEquals(FILE_SIZE, actual.length);
1542     }
1543 
1544     @Test
1545     public void testToByteArray_URLConnection() throws Exception {
1546         final byte[] actual;
1547         try (CloseableURLConnection urlConnection = CloseableURLConnection.open(testFile.toURI())) {
1548             actual = IOUtils.toByteArray(urlConnection);
1549         }
1550         assertEquals(FILE_SIZE, actual.length);
1551     }
1552 
1553     @Test
1554     public void testToCharArray_InputStream() throws Exception {
1555         try (InputStream fin = Files.newInputStream(testFilePath)) {
1556             final char[] out = IOUtils.toCharArray(fin);
1557             assertNotNull(out);
1558             assertEquals(0, fin.available(), "Not all chars were read");
1559             assertEquals(FILE_SIZE, out.length, "Wrong output size");
1560             TestUtils.assertEqualContent(out, testFile);
1561         }
1562     }
1563 
1564     @Test
1565     public void testToCharArray_InputStream_CharsetName() throws Exception {
1566         try (InputStream fin = Files.newInputStream(testFilePath)) {
1567             final char[] out = IOUtils.toCharArray(fin, UTF_8);
1568             assertNotNull(out);
1569             assertEquals(0, fin.available(), "Not all chars were read");
1570             assertEquals(FILE_SIZE, out.length, "Wrong output size");
1571             TestUtils.assertEqualContent(out, testFile);
1572         }
1573     }
1574 
1575     @Test
1576     public void testToCharArray_Reader() throws Exception {
1577         try (Reader fr = Files.newBufferedReader(testFilePath)) {
1578             final char[] out = IOUtils.toCharArray(fr);
1579             assertNotNull(out);
1580             assertEquals(FILE_SIZE, out.length, "Wrong output size");
1581             TestUtils.assertEqualContent(out, testFile);
1582         }
1583     }
1584 
1585     /**
1586      * Test for {@link IOUtils#toInputStream(CharSequence)} and {@link IOUtils#toInputStream(CharSequence, String)}.
1587      * Note, this test utilizes on {@link IOUtils#toByteArray(InputStream)} and so relies on
1588      * {@link #testToByteArray_InputStream()} to ensure this method functions correctly.
1589      *
1590      * @throws Exception on error
1591      */
1592     @Test
1593     public void testToInputStream_CharSequence() throws Exception {
1594         final CharSequence csq = new StringBuilder("Abc123Xyz!");
1595         InputStream inStream = IOUtils.toInputStream(csq); // deliberately testing deprecated method
1596         byte[] bytes = IOUtils.toByteArray(inStream);
1597         assertEqualContent(csq.toString().getBytes(), bytes);
1598         inStream = IOUtils.toInputStream(csq, (String) null);
1599         bytes = IOUtils.toByteArray(inStream);
1600         assertEqualContent(csq.toString().getBytes(), bytes);
1601         inStream = IOUtils.toInputStream(csq, UTF_8);
1602         bytes = IOUtils.toByteArray(inStream);
1603         assertEqualContent(csq.toString().getBytes(StandardCharsets.UTF_8), bytes);
1604     }
1605 
1606     /**
1607      * Test for {@link IOUtils#toInputStream(String)} and {@link IOUtils#toInputStream(String, String)}. Note, this test
1608      * utilizes on {@link IOUtils#toByteArray(InputStream)} and so relies on
1609      * {@link #testToByteArray_InputStream()} to ensure this method functions correctly.
1610      *
1611      * @throws Exception on error
1612      */
1613     @Test
1614     public void testToInputStream_String() throws Exception {
1615         final String str = "Abc123Xyz!";
1616         InputStream inStream = IOUtils.toInputStream(str);
1617         byte[] bytes = IOUtils.toByteArray(inStream);
1618         assertEqualContent(str.getBytes(), bytes);
1619         inStream = IOUtils.toInputStream(str, (String) null);
1620         bytes = IOUtils.toByteArray(inStream);
1621         assertEqualContent(str.getBytes(), bytes);
1622         inStream = IOUtils.toInputStream(str, UTF_8);
1623         bytes = IOUtils.toByteArray(inStream);
1624         assertEqualContent(str.getBytes(StandardCharsets.UTF_8), bytes);
1625     }
1626 
1627     @Test
1628     public void testToString_ByteArray() throws Exception {
1629         try (InputStream fin = Files.newInputStream(testFilePath)) {
1630             final byte[] in = IOUtils.toByteArray(fin);
1631             // Create our byte[]. Rely on testInputStreamToByteArray() to make sure this is valid.
1632             final String str = IOUtils.toString(in);
1633             assertEqualContent(in, str.getBytes());
1634         }
1635     }
1636 
1637     @Test
1638     public void testToString_InputStream() throws Exception {
1639         try (InputStream fin = Files.newInputStream(testFilePath)) {
1640             final String out = IOUtils.toString(fin);
1641             assertNotNull(out);
1642             assertEquals(0, fin.available(), "Not all bytes were read");
1643             assertEquals(FILE_SIZE, out.length(), "Wrong output size");
1644         }
1645     }
1646 
1647     @Test
1648     public void testToString_InputStreamSupplier() throws Exception {
1649         final String out = IOUtils.toString(() -> Files.newInputStream(testFilePath), Charset.defaultCharset());
1650         assertNotNull(out);
1651         assertEquals(FILE_SIZE, out.length(), "Wrong output size");
1652         assertNull(IOUtils.toString(null, Charset.defaultCharset(), () -> null));
1653         assertNull(IOUtils.toString(() -> null, Charset.defaultCharset(), () -> null));
1654         assertEquals("A", IOUtils.toString(null, Charset.defaultCharset(), () -> "A"));
1655     }
1656 
1657     @Test
1658     public void testToString_Reader() throws Exception {
1659         try (Reader fin = Files.newBufferedReader(testFilePath)) {
1660             final String out = IOUtils.toString(fin);
1661             assertNotNull(out);
1662             assertEquals(FILE_SIZE, out.length(), "Wrong output size");
1663         }
1664     }
1665 
1666     @Test
1667     public void testToString_URI() throws Exception {
1668         final URI url = testFile.toURI();
1669         final String out = IOUtils.toString(url);
1670         assertNotNull(out);
1671         assertEquals(FILE_SIZE, out.length(), "Wrong output size");
1672     }
1673 
1674     private void testToString_URI(final String encoding) throws Exception {
1675         final URI uri = testFile.toURI();
1676         final String out = IOUtils.toString(uri, encoding);
1677         assertNotNull(out);
1678         assertEquals(FILE_SIZE, out.length(), "Wrong output size");
1679     }
1680 
1681     @Test
1682     public void testToString_URI_CharsetName() throws Exception {
1683         testToString_URI(StandardCharsets.US_ASCII.name());
1684     }
1685 
1686     @Test
1687     public void testToString_URI_CharsetNameNull() throws Exception {
1688         testToString_URI(null);
1689     }
1690 
1691     @Test
1692     public void testToString_URL() throws Exception {
1693         final URL url = testFile.toURI().toURL();
1694         final String out = IOUtils.toString(url);
1695         assertNotNull(out);
1696         assertEquals(FILE_SIZE, out.length(), "Wrong output size");
1697     }
1698 
1699     private void testToString_URL(final String encoding) throws Exception {
1700         final URL url = testFile.toURI().toURL();
1701         final String out = IOUtils.toString(url, encoding);
1702         assertNotNull(out);
1703         assertEquals(FILE_SIZE, out.length(), "Wrong output size");
1704     }
1705 
1706     @Test
1707     public void testToString_URL_CharsetName() throws Exception {
1708         testToString_URL(StandardCharsets.US_ASCII.name());
1709     }
1710 
1711     @Test
1712     public void testToString_URL_CharsetNameNull() throws Exception {
1713         testToString_URL(null);
1714     }
1715 
1716     /**
1717      * IO-764 IOUtils.write() throws NegativeArraySizeException while writing big strings.
1718      * <pre>
1719      * java.lang.OutOfMemoryError: Java heap space
1720      *     at java.lang.StringCoding.encode(StringCoding.java:350)
1721      *     at java.lang.String.getBytes(String.java:941)
1722      *     at org.apache.commons.io.IOUtils.write(IOUtils.java:3367)
1723      *     at org.apache.commons.io.IOUtilsTest.testBigString(IOUtilsTest.java:1659)
1724      * </pre>
1725      */
1726     @Test
1727     public void testWriteBigString() throws IOException {
1728         // 3_000_000 is a size that we can allocate for the test string with Java 8 on the command line as:
1729         // mvn clean test -Dtest=IOUtilsTest -DtestBigString=3000000
1730         // 6_000_000 failed with the above
1731         //
1732         // TODO Can we mock the test string for this test to pretend to be larger?
1733         // Mocking the length seems simple but how about the data?
1734         final int repeat = Integer.getInteger("testBigString", 3_000_000);
1735         final String data;
1736         try {
1737             data = StringUtils.repeat("\uD83D", repeat);
1738         } catch (final OutOfMemoryError e) {
1739             System.err.printf("Don't fail the test if we cannot build the fixture, just log, fixture size = %,d%n.", repeat);
1740             e.printStackTrace();
1741             return;
1742         }
1743         try (CountingOutputStream os = new CountingOutputStream(NullOutputStream.INSTANCE)) {
1744             IOUtils.write(data, os, StandardCharsets.UTF_8);
1745             assertEquals(repeat, os.getByteCount());
1746         }
1747     }
1748 
1749     @Test
1750     public void testWriteLines() throws IOException {
1751         final String[] data = {"The", "quick"};
1752         final ByteArrayOutputStream out = new ByteArrayOutputStream();
1753         IOUtils.writeLines(Arrays.asList(data), "\n", out, StandardCharsets.UTF_16.name());
1754         final String result = new String(out.toByteArray(), StandardCharsets.UTF_16);
1755         assertEquals("The\nquick\n", result);
1756     }
1757 
1758     @Test
1759     public void testWriteLittleString() throws IOException {
1760         final String data = "\uD83D";
1761         // White-box test to check that not closing the internal channel is not a problem.
1762         for (int i = 0; i < 1_000_000; i++) {
1763             try (CountingOutputStream os = new CountingOutputStream(NullOutputStream.INSTANCE)) {
1764                 IOUtils.write(data, os, StandardCharsets.UTF_8);
1765                 assertEquals(data.length(), os.getByteCount());
1766             }
1767         }
1768     }
1769 
1770 }