• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertNotEquals;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertNull;
25 import static org.junit.jupiter.api.Assertions.assertSame;
26 import static org.junit.jupiter.api.Assertions.assertThrows;
27 import static org.junit.jupiter.api.Assertions.assertTrue;
28 import static org.junit.jupiter.api.Assertions.fail;
29 
30 import java.io.BufferedOutputStream;
31 import java.io.ByteArrayOutputStream;
32 import java.io.File;
33 import java.io.FileInputStream;
34 import java.io.FileNotFoundException;
35 import java.io.FileOutputStream;
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.io.OutputStream;
39 import java.math.BigInteger;
40 import java.net.URL;
41 import java.nio.charset.Charset;
42 import java.nio.charset.StandardCharsets;
43 import java.nio.charset.UnsupportedCharsetException;
44 import java.nio.file.Files;
45 import java.nio.file.Path;
46 import java.nio.file.Paths;
47 import java.nio.file.StandardCopyOption;
48 import java.nio.file.attribute.AclFileAttributeView;
49 import java.nio.file.attribute.FileTime;
50 import java.nio.file.attribute.PosixFilePermission;
51 import java.nio.file.attribute.PosixFilePermissions;
52 import java.time.Instant;
53 import java.time.LocalDate;
54 import java.time.LocalDateTime;
55 import java.time.LocalTime;
56 import java.time.OffsetDateTime;
57 import java.time.OffsetTime;
58 import java.time.ZoneId;
59 import java.time.ZoneOffset;
60 import java.time.ZonedDateTime;
61 import java.util.ArrayList;
62 import java.util.Arrays;
63 import java.util.Collection;
64 import java.util.Collections;
65 import java.util.Date;
66 import java.util.GregorianCalendar;
67 import java.util.HashMap;
68 import java.util.Iterator;
69 import java.util.List;
70 import java.util.Map;
71 import java.util.Set;
72 import java.util.concurrent.TimeUnit;
73 import java.util.stream.Collectors;
74 import java.util.zip.CRC32;
75 import java.util.zip.Checksum;
76 
77 import org.apache.commons.io.file.AbstractTempDirTest;
78 import org.apache.commons.io.file.PathUtils;
79 import org.apache.commons.io.file.PathUtilsIsEmptyTest;
80 import org.apache.commons.io.file.TempDirectory;
81 import org.apache.commons.io.file.TempFile;
82 import org.apache.commons.io.filefilter.IOFileFilter;
83 import org.apache.commons.io.filefilter.NameFileFilter;
84 import org.apache.commons.io.filefilter.WildcardFileFilter;
85 import org.apache.commons.io.test.TestUtils;
86 import org.apache.commons.lang3.SystemUtils;
87 import org.junit.jupiter.api.Assertions;
88 import org.junit.jupiter.api.BeforeEach;
89 import org.junit.jupiter.api.Disabled;
90 import org.junit.jupiter.api.Test;
91 import org.junit.jupiter.api.condition.EnabledIf;
92 import org.junit.jupiter.params.ParameterizedTest;
93 import org.junit.jupiter.params.provider.ValueSource;
94 
95 /**
96  * Tests {@link FileUtils}.
97  */
98 @SuppressWarnings({"deprecation", "ResultOfMethodCallIgnored"}) // unit tests include tests of many deprecated methods
99 public class FileUtilsTest extends AbstractTempDirTest {
100 
101     /**
102      * DirectoryWalker implementation that recursively lists all files and directories.
103      */
104     static class ListDirectoryWalker extends DirectoryWalker<File> {
105 
ListDirectoryWalker()106         ListDirectoryWalker() {
107         }
108 
109         @Override
handleDirectoryStart(final File directory, final int depth, final Collection<File> results)110         protected void handleDirectoryStart(final File directory, final int depth, final Collection<File> results) throws IOException {
111             // Add all directories except the starting directory
112             if (depth > 0) {
113                 results.add(directory);
114             }
115         }
116 
117         @Override
handleFile(final File file, final int depth, final Collection<File> results)118         protected void handleFile(final File file, final int depth, final Collection<File> results) throws IOException {
119             results.add(file);
120         }
121 
list(final File startDirectory)122         List<File> list(final File startDirectory) throws IOException {
123             final ArrayList<File> files = new ArrayList<>();
124             walk(startDirectory, files);
125             return files;
126         }
127     }
128 
129     private static final String UTF_8 = StandardCharsets.UTF_8.name();
130 
131     /** Test data. */
132     private static final long DATE3 = 1_000_000_002_000L;
133 
134     /** Test data. */
135     private static final long DATE2 = 1_000_000_001_000L;
136 
137     /** Test data. */
138     private static final long DATE1 = 1_000_000_000_000L;
139 
140     /**
141      * Size of test directory.
142      */
143     private static final int TEST_DIRECTORY_SIZE = 0;
144 
145     /**
146      * Size of test directory.
147      */
148     private static final BigInteger TEST_DIRECTORY_SIZE_BI = BigInteger.ZERO;
149 
150     /**
151      * Size (greater of zero) of test file.
152      */
153     private static final BigInteger TEST_DIRECTORY_SIZE_GT_ZERO_BI = BigInteger.valueOf(100);
154 
155     /**
156      * List files recursively
157      */
158     private static final ListDirectoryWalker LIST_WALKER = new ListDirectoryWalker();
159 
160     private File testFile1;
161     private File testFile2;
162 
163     private long testFile1Size;
164 
165     private long testFile2Size;
166 
assertContentMatchesAfterCopyURLToFileFor(final String resourceName, final File destination)167     private void assertContentMatchesAfterCopyURLToFileFor(final String resourceName, final File destination) throws IOException {
168         FileUtils.copyURLToFile(getClass().getResource(resourceName), destination);
169 
170         try (InputStream fis = Files.newInputStream(destination.toPath());
171              InputStream expected = getClass().getResourceAsStream(resourceName)) {
172             assertTrue(IOUtils.contentEquals(expected, fis), "Content is not equal.");
173         }
174     }
175 
backDateFile10Minutes(final File testFile)176     private void backDateFile10Minutes(final File testFile) throws IOException {
177         final long mins10 = 1000 * 60 * 10;
178         final long lastModified1 = getLastModifiedMillis(testFile);
179         assertTrue(setLastModifiedMillis(testFile, lastModified1 - mins10));
180         // ensure it was changed
181         assertNotEquals(getLastModifiedMillis(testFile), lastModified1, "Should have changed source date");
182     }
183 
consumeRemaining(final Iterator<File> iterator)184     private void consumeRemaining(final Iterator<File> iterator) {
185         if (iterator != null) {
186             iterator.forEachRemaining(e -> {});
187         }
188     }
189 
createCircularOsSymLink(final String linkName, final String targetName)190     private Path createCircularOsSymLink(final String linkName, final String targetName) throws IOException {
191         return Files.createSymbolicLink(Paths.get(linkName), Paths.get(targetName));
192     }
193 
194     /**
195      * May throw java.nio.file.FileSystemException: C:\Users\...\FileUtilsTestCase\cycle: A required privilege is not held
196      * by the client. On Windows, you are fine if you run a terminal with admin karma.
197      */
createCircularSymLink(final File file)198     private void createCircularSymLink(final File file) throws IOException {
199         assertTrue(file.exists());
200         final String linkName = file + "/cycle";
201         final String targetName = file + "/..";
202         assertTrue(file.exists());
203         final Path linkPath = Paths.get(linkName);
204         assertFalse(Files.exists(linkPath));
205         final Path targetPath = Paths.get(targetName);
206         assertTrue(Files.exists(targetPath));
207         try {
208             // May throw java.nio.file.FileSystemException: C:\Users\...\FileUtilsTestCase\cycle: A required privilege is not held by the client.
209             // On Windows, you are fine if you run a terminal with admin karma.
210             Files.createSymbolicLink(linkPath, targetPath);
211         } catch (final UnsupportedOperationException e) {
212             e.printStackTrace();
213             createCircularOsSymLink(linkName, targetName);
214         }
215         // Sanity check:
216         assertTrue(Files.isSymbolicLink(linkPath), () -> "Expected a sym link here: " + linkName);
217     }
218 
createFilesForTestCopyDirectory(final File grandParentDir, final File parentDir, final File childDir)219     private void createFilesForTestCopyDirectory(final File grandParentDir, final File parentDir, final File childDir) throws IOException {
220         final File childDir2 = new File(parentDir, "child2");
221         final File grandChildDir = new File(childDir, "grandChild");
222         final File grandChild2Dir = new File(childDir2, "grandChild2");
223         final File file1 = new File(grandParentDir, "file1.txt");
224         final File file2 = new File(parentDir, "file2.txt");
225         final File file3 = new File(childDir, "file3.txt");
226         final File file4 = new File(childDir2, "file4.txt");
227         final File file5 = new File(grandChildDir, "file5.txt");
228         final File file6 = new File(grandChild2Dir, "file6.txt");
229         FileUtils.deleteDirectory(grandParentDir);
230         grandChildDir.mkdirs();
231         grandChild2Dir.mkdirs();
232         FileUtils.writeStringToFile(file1, "File 1 in grandparent", "UTF8");
233         FileUtils.writeStringToFile(file2, "File 2 in parent", "UTF8");
234         FileUtils.writeStringToFile(file3, "File 3 in child", "UTF8");
235         FileUtils.writeStringToFile(file4, "File 4 in child2", "UTF8");
236         FileUtils.writeStringToFile(file5, "File 5 in grandChild", "UTF8");
237         FileUtils.writeStringToFile(file6, "File 6 in grandChild2", "UTF8");
238     }
239 
createTempSymlinkedRelativeDir()240     private Path createTempSymlinkedRelativeDir() throws IOException {
241         final Path targetDir = tempDirPath.resolve("subdir");
242         final Path symlinkDir = tempDirPath.resolve("symlinked-dir");
243         Files.createDirectory(targetDir);
244         Files.createSymbolicLink(symlinkDir, targetDir);
245         return symlinkDir;
246     }
247 
getFilePathSet(final List<File> files)248     private Set<String> getFilePathSet(final List<File> files) {
249         return files.stream().map(f -> {
250             try {
251                 return f.getCanonicalPath();
252             } catch (final IOException e) {
253                 throw new RuntimeException(e);
254             }
255         }).collect(Collectors.toSet());
256     }
257 
258     private long getLastModifiedMillis(final File file) throws IOException {
259         return FileUtils.lastModified(file);
260     }
261 
262     private String getName() {
263         return this.getClass().getSimpleName();
264     }
265 
266     private void iterateFilesAndDirs(final File dir, final IOFileFilter fileFilter,
267         final IOFileFilter dirFilter, final Collection<File> expectedFilesAndDirs) {
268         final Iterator<File> iterator;
269         int filesCount = 0;
270         iterator = FileUtils.iterateFilesAndDirs(dir, fileFilter, dirFilter);
271         try {
272             final List<File> actualFiles = new ArrayList<>();
273             while (iterator.hasNext()) {
274                 filesCount++;
275                 final File file = iterator.next();
276                 actualFiles.add(file);
277                 assertTrue(expectedFilesAndDirs.contains(file),
278                     () -> "Unexpected directory/file " + file + ", expected one of " + expectedFilesAndDirs);
279             }
280             assertEquals(expectedFilesAndDirs.size(), filesCount, actualFiles::toString);
281         } finally {
282             // MUST consume until the end in order to close the underlying stream.
283             consumeRemaining(iterator);
284         }
285     }
286 
287     void openOutputStream_noParent(final boolean createFile) throws Exception {
288         final File file = new File("test.txt");
289         assertNull(file.getParentFile());
290         try {
291             if (createFile) {
292                 TestUtils.createLineBasedFile(file, new String[]{"Hello"});
293             }
294             try (FileOutputStream out = FileUtils.openOutputStream(file)) {
295                 out.write(0);
296             }
297             assertTrue(file.exists());
298         } finally {
299             if (!file.delete()) {
300                 file.deleteOnExit();
301             }
302         }
303     }
304 
305     private boolean setLastModifiedMillis(final File testFile, final long millis) {
306         return testFile.setLastModified(millis);
307 //        try {
308 //            Files.setLastModifiedTime(testFile.toPath(), FileTime.fromMillis(millis));
309 //        } catch (IOException e) {
310 //            return false;
311 //        }
312 //        return true;
313     }
314 
315     @BeforeEach
316     public void setUp() throws Exception {
317         testFile1 = new File(tempDirFile, "file1-test.txt");
318         testFile2 = new File(tempDirFile, "file1a-test.txt");
319 
320         testFile1Size = testFile1.length();
321         testFile2Size = testFile2.length();
322         if (!testFile1.getParentFile().exists()) {
323             fail("Cannot create file " + testFile1
324                     + " as the parent directory does not exist");
325         }
326         try (BufferedOutputStream output3 =
327                 new BufferedOutputStream(Files.newOutputStream(testFile1.toPath()))) {
328             TestUtils.generateTestData(output3, testFile1Size);
329         }
330         if (!testFile2.getParentFile().exists()) {
331             fail("Cannot create file " + testFile2
332                     + " as the parent directory does not exist");
333         }
334         try (BufferedOutputStream output2 =
335                 new BufferedOutputStream(Files.newOutputStream(testFile2.toPath()))) {
336             TestUtils.generateTestData(output2, testFile2Size);
337         }
338         FileUtils.deleteDirectory(tempDirFile);
339         tempDirFile.mkdirs();
340         if (!testFile1.getParentFile().exists()) {
341             fail("Cannot create file " + testFile1
342                     + " as the parent directory does not exist");
343         }
344         try (BufferedOutputStream output1 =
345                 new BufferedOutputStream(Files.newOutputStream(testFile1.toPath()))) {
346             TestUtils.generateTestData(output1, testFile1Size);
347         }
348         if (!testFile2.getParentFile().exists()) {
349             fail("Cannot create file " + testFile2
350                     + " as the parent directory does not exist");
351         }
352         try (BufferedOutputStream output =
353                 new BufferedOutputStream(Files.newOutputStream(testFile2.toPath()))) {
354             TestUtils.generateTestData(output, testFile2Size);
355         }
356     }
357 
358     @Test
359     public void test_openInputStream_exists() throws Exception {
360         final File file = new File(tempDirFile, "test.txt");
361         TestUtils.createLineBasedFile(file, new String[]{"Hello"});
362         try (FileInputStream in = FileUtils.openInputStream(file)) {
363             assertEquals('H', in.read());
364         }
365     }
366 
367     @Test
368     public void test_openInputStream_existsButIsDirectory() {
369         final File directory = new File(tempDirFile, "subdir");
370         directory.mkdirs();
371         assertThrows(IOException.class, () -> FileUtils.openInputStream(directory));
372     }
373 
374     @Test
375     public void test_openInputStream_notExists() {
376         final File directory = new File(tempDirFile, "test.txt");
377         assertThrows(IOException.class, () -> FileUtils.openInputStream(directory));
378     }
379 
380     @Test
381     public void test_openOutputStream_exists() throws Exception {
382         final File file = new File(tempDirFile, "test.txt");
383         TestUtils.createLineBasedFile(file, new String[]{"Hello"});
384         try (FileOutputStream out = FileUtils.openOutputStream(file)) {
385             out.write(0);
386         }
387         assertTrue(file.exists());
388     }
389 
390     @Test
391     public void test_openOutputStream_existsButIsDirectory() {
392         final File directory = new File(tempDirFile, "subdir");
393         directory.mkdirs();
394         assertThrows(IllegalArgumentException.class, () -> FileUtils.openOutputStream(directory));
395     }
396 
397     /**
398      * Requires admin privileges on Windows.
399      *
400      * @throws Exception For example java.nio.file.FileSystemException:
401      *                   C:\Users\you\AppData\Local\Temp\junit2324629522183300191\FileUtilsTest8613879743106252609\symlinked-dir: A required privilege is
402      *                   not held by the client.
403      */
404     @Test
405     public void test_openOutputStream_intoExistingSymlinkedDir() throws Exception {
406         final Path symlinkedDir = createTempSymlinkedRelativeDir();
407 
408         final File file = symlinkedDir.resolve("test.txt").toFile();
409         try (FileOutputStream out = FileUtils.openOutputStream(file)) {
410             out.write(0);
411         }
412         assertTrue(file.exists());
413     }
414 
415     @Test
416     public void test_openOutputStream_noParentCreateFile() throws Exception {
417         openOutputStream_noParent(true);
418     }
419 
420     @Test
421     public void test_openOutputStream_noParentNoFile() throws Exception {
422         openOutputStream_noParent(false);
423     }
424 
425     @Test
426     public void test_openOutputStream_notExists() throws Exception {
427         final File file = new File(tempDirFile, "a/test.txt");
428         try (FileOutputStream out = FileUtils.openOutputStream(file)) {
429             out.write(0);
430         }
431         assertTrue(file.exists());
432     }
433 
434     @Test
435     public void test_openOutputStream_notExistsCannotCreate() {
436         // according to Wikipedia, most filing systems have a 256 limit on filename
437         final String longStr =
438                 "abcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyz" +
439                         "abcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyz" +
440                         "abcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyz" +
441                         "abcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyz" +
442                         "abcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyz" +
443                         "abcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyzabcdevwxyz";  // 300 chars
444         final File file = new File(tempDirFile, "a/" + longStr + "/test.txt");
445         assertThrows(IOException.class, () -> FileUtils.openOutputStream(file));
446     }
447 
448     // byteCountToDisplaySize
449     @Test
450     public void testByteCountToDisplaySizeBigInteger() {
451         final BigInteger b1023 = BigInteger.valueOf(1023);
452         final BigInteger b1025 = BigInteger.valueOf(1025);
453         final BigInteger KB1 = BigInteger.valueOf(1024);
454         final BigInteger MB1 = KB1.multiply(KB1);
455         final BigInteger GB1 = MB1.multiply(KB1);
456         final BigInteger GB2 = GB1.add(GB1);
457         final BigInteger TB1 = GB1.multiply(KB1);
458         final BigInteger PB1 = TB1.multiply(KB1);
459         final BigInteger EB1 = PB1.multiply(KB1);
460         assertEquals("0 bytes", FileUtils.byteCountToDisplaySize(BigInteger.ZERO));
461         assertEquals("1 bytes", FileUtils.byteCountToDisplaySize(BigInteger.ONE));
462         assertEquals("1023 bytes", FileUtils.byteCountToDisplaySize(b1023));
463         assertEquals("1 KB", FileUtils.byteCountToDisplaySize(KB1));
464         assertEquals("1 KB", FileUtils.byteCountToDisplaySize(b1025));
465         assertEquals("1023 KB", FileUtils.byteCountToDisplaySize(MB1.subtract(BigInteger.ONE)));
466         assertEquals("1 MB", FileUtils.byteCountToDisplaySize(MB1));
467         assertEquals("1 MB", FileUtils.byteCountToDisplaySize(MB1.add(BigInteger.ONE)));
468         assertEquals("1023 MB", FileUtils.byteCountToDisplaySize(GB1.subtract(BigInteger.ONE)));
469         assertEquals("1 GB", FileUtils.byteCountToDisplaySize(GB1));
470         assertEquals("1 GB", FileUtils.byteCountToDisplaySize(GB1.add(BigInteger.ONE)));
471         assertEquals("2 GB", FileUtils.byteCountToDisplaySize(GB2));
472         assertEquals("1 GB", FileUtils.byteCountToDisplaySize(GB2.subtract(BigInteger.ONE)));
473         assertEquals("1 TB", FileUtils.byteCountToDisplaySize(TB1));
474         assertEquals("1 PB", FileUtils.byteCountToDisplaySize(PB1));
475         assertEquals("1 EB", FileUtils.byteCountToDisplaySize(EB1));
476         assertEquals("7 EB", FileUtils.byteCountToDisplaySize(Long.MAX_VALUE));
477         // Other MAX_VALUEs
478         assertEquals("63 KB", FileUtils.byteCountToDisplaySize(BigInteger.valueOf(Character.MAX_VALUE)));
479         assertEquals("31 KB", FileUtils.byteCountToDisplaySize(BigInteger.valueOf(Short.MAX_VALUE)));
480         assertEquals("1 GB", FileUtils.byteCountToDisplaySize(BigInteger.valueOf(Integer.MAX_VALUE)));
481     }
482 
483     @SuppressWarnings("NumericOverflow")
484     @Test
485     public void testByteCountToDisplaySizeLong() {
486         assertEquals("0 bytes", FileUtils.byteCountToDisplaySize(0));
487         assertEquals("1 bytes", FileUtils.byteCountToDisplaySize(1));
488         assertEquals("1023 bytes", FileUtils.byteCountToDisplaySize(1023));
489         assertEquals("1 KB", FileUtils.byteCountToDisplaySize(1024));
490         assertEquals("1 KB", FileUtils.byteCountToDisplaySize(1025));
491         assertEquals("1023 KB", FileUtils.byteCountToDisplaySize(1024 * 1023));
492         assertEquals("1 MB", FileUtils.byteCountToDisplaySize(1024 * 1024));
493         assertEquals("1 MB", FileUtils.byteCountToDisplaySize(1024 * 1025));
494         assertEquals("1023 MB", FileUtils.byteCountToDisplaySize(1024 * 1024 * 1023));
495         assertEquals("1 GB", FileUtils.byteCountToDisplaySize(1024 * 1024 * 1024));
496         assertEquals("1 GB", FileUtils.byteCountToDisplaySize(1024 * 1024 * 1025));
497         assertEquals("2 GB", FileUtils.byteCountToDisplaySize(1024L * 1024 * 1024 * 2));
498         assertEquals("1 GB", FileUtils.byteCountToDisplaySize(1024L * 1024 * 1024 * 2 - 1));
499         assertEquals("1 TB", FileUtils.byteCountToDisplaySize(1024L * 1024 * 1024 * 1024));
500         assertEquals("1 PB", FileUtils.byteCountToDisplaySize(1024L * 1024 * 1024 * 1024 * 1024));
501         assertEquals("1 EB", FileUtils.byteCountToDisplaySize(1024L * 1024 * 1024 * 1024 * 1024 * 1024));
502         assertEquals("7 EB", FileUtils.byteCountToDisplaySize(Long.MAX_VALUE));
503         // Other MAX_VALUEs
504         assertEquals("63 KB", FileUtils.byteCountToDisplaySize(Character.MAX_VALUE));
505         assertEquals("31 KB", FileUtils.byteCountToDisplaySize(Short.MAX_VALUE));
506         assertEquals("1 GB", FileUtils.byteCountToDisplaySize(Integer.MAX_VALUE));
507     }
508 
509     @Test
510     public void testByteCountToDisplaySizeNumber() {
511         assertEquals("0 bytes", FileUtils.byteCountToDisplaySize(Integer.valueOf(0)));
512         assertEquals("1 bytes", FileUtils.byteCountToDisplaySize(Integer.valueOf(1)));
513         assertEquals("1023 bytes", FileUtils.byteCountToDisplaySize(Integer.valueOf(1023)));
514         assertEquals("1 KB", FileUtils.byteCountToDisplaySize(Integer.valueOf(1024)));
515         assertEquals("1 KB", FileUtils.byteCountToDisplaySize(Integer.valueOf(1025)));
516         assertEquals("1023 KB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024 * 1023)));
517         assertEquals("1 MB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024 * 1024)));
518         assertEquals("1 MB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024 * 1025)));
519         assertEquals("1023 MB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024 * 1024 * 1023)));
520         assertEquals("1 GB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024 * 1024 * 1024)));
521         assertEquals("1 GB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024 * 1024 * 1025)));
522         assertEquals("2 GB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024L * 1024 * 1024 * 2)));
523         assertEquals("1 GB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024L * 1024 * 1024 * 2 - 1)));
524         assertEquals("1 TB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024L * 1024 * 1024 * 1024)));
525         assertEquals("1 PB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024L * 1024 * 1024 * 1024 * 1024)));
526         assertEquals("1 EB", FileUtils.byteCountToDisplaySize(Long.valueOf(1024L * 1024 * 1024 * 1024 * 1024 * 1024)));
527         assertEquals("7 EB", FileUtils.byteCountToDisplaySize(Long.valueOf(Long.MAX_VALUE)));
528         // Other MAX_VALUEs
529         assertEquals("63 KB", FileUtils.byteCountToDisplaySize(Integer.valueOf(Character.MAX_VALUE)));
530         assertEquals("31 KB", FileUtils.byteCountToDisplaySize(Short.valueOf(Short.MAX_VALUE)));
531         assertEquals("1 GB", FileUtils.byteCountToDisplaySize(Integer.valueOf(Integer.MAX_VALUE)));
532     }
533 
534     @Test
535     public void testChecksum() throws Exception {
536         // create a test file
537         final String text = "Imagination is more important than knowledge - Einstein";
538         final File file = new File(tempDirFile, "checksum-test.txt");
539         FileUtils.writeStringToFile(file, text, "US-ASCII");
540 
541         // compute the expected checksum
542         final Checksum expectedChecksum = new CRC32();
543         expectedChecksum.update(text.getBytes(StandardCharsets.US_ASCII), 0, text.length());
544         final long expectedValue = expectedChecksum.getValue();
545 
546         // compute the checksum of the file
547         final Checksum testChecksum = new CRC32();
548         final Checksum resultChecksum = FileUtils.checksum(file, testChecksum);
549         final long resultValue = resultChecksum.getValue();
550 
551         assertSame(testChecksum, resultChecksum);
552         assertEquals(expectedValue, resultValue);
553     }
554 
555     @Test
556     public void testChecksumCRC32() throws Exception {
557         // create a test file
558         final String text = "Imagination is more important than knowledge - Einstein";
559         final File file = new File(tempDirFile, "checksum-test.txt");
560         FileUtils.writeStringToFile(file, text, "US-ASCII");
561 
562         // compute the expected checksum
563         final Checksum expectedChecksum = new CRC32();
564         expectedChecksum.update(text.getBytes(StandardCharsets.US_ASCII), 0, text.length());
565         final long expectedValue = expectedChecksum.getValue();
566 
567         // compute the checksum of the file
568         final long resultValue = FileUtils.checksumCRC32(file);
569 
570         assertEquals(expectedValue, resultValue);
571     }
572 
573     @Test
574     public void testChecksumDouble() throws Exception {
575         // create a test file
576         final String text1 = "Imagination is more important than knowledge - Einstein";
577         final File file1 = new File(tempDirFile, "checksum-test.txt");
578         FileUtils.writeStringToFile(file1, text1, "US-ASCII");
579 
580         // create a second test file
581         final String text2 = "To be or not to be - Shakespeare";
582         final File file2 = new File(tempDirFile, "checksum-test2.txt");
583         FileUtils.writeStringToFile(file2, text2, "US-ASCII");
584 
585         // compute the expected checksum
586         final Checksum expectedChecksum = new CRC32();
587         expectedChecksum.update(text1.getBytes(StandardCharsets.US_ASCII), 0, text1.length());
588         expectedChecksum.update(text2.getBytes(StandardCharsets.US_ASCII), 0, text2.length());
589         final long expectedValue = expectedChecksum.getValue();
590 
591         // compute the checksum of the file
592         final Checksum testChecksum = new CRC32();
593         FileUtils.checksum(file1, testChecksum);
594         FileUtils.checksum(file2, testChecksum);
595         final long resultValue = testChecksum.getValue();
596 
597         assertEquals(expectedValue, resultValue);
598     }
599 
600     @Test
601     public void testChecksumOnDirectory() {
602         assertThrows(IllegalArgumentException.class, () -> FileUtils.checksum(FileUtils.current(), new CRC32()));
603     }
604 
605     @Test
606     public void testChecksumOnNullChecksum() throws Exception {
607         // create a test file
608         final String text = "Imagination is more important than knowledge - Einstein";
609         final File file = new File(tempDirFile, "checksum-test.txt");
610         FileUtils.writeStringToFile(file, text, "US-ASCII");
611         assertThrows(NullPointerException.class, () -> FileUtils.checksum(file, null));
612     }
613 
614     @Test
615     public void testChecksumOnNullFile() {
616         assertThrows(NullPointerException.class, () -> FileUtils.checksum(null, new CRC32()));
617     }
618 
619     // Compare sizes of a directory tree using long and BigInteger methods
620     @Test
621     public void testCompareSizeOf() {
622         final File start = new File("src/test/java");
623         final long sizeLong1 = FileUtils.sizeOf(start);
624         final BigInteger sizeBig = FileUtils.sizeOfAsBigInteger(start);
625         final long sizeLong2 = FileUtils.sizeOf(start);
626         assertEquals(sizeLong1, sizeLong2, "Size should not change");
627         assertEquals(sizeLong1, sizeBig.longValue(), "longSize should equal BigSize");
628     }
629 
630     @Test
631     public void testContentEquals() throws Exception {
632         // Non-existent files
633         final File file = new File(tempDirFile, getName());
634         final File file2 = new File(tempDirFile, getName() + "2");
635         assertTrue(FileUtils.contentEquals(null, null));
636         assertFalse(FileUtils.contentEquals(null, file));
637         assertFalse(FileUtils.contentEquals(file, null));
638         // both don't  exist
639         assertTrue(FileUtils.contentEquals(file, file));
640         assertTrue(FileUtils.contentEquals(file, file2));
641         assertTrue(FileUtils.contentEquals(file2, file2));
642         assertTrue(FileUtils.contentEquals(file2, file));
643 
644         // Directories
645         assertThrows(IllegalArgumentException.class, () -> FileUtils.contentEquals(tempDirFile, tempDirFile));
646 
647         // Different files
648         final File objFile1 =
649                 new File(tempDirFile, getName() + ".object");
650         FileUtils.copyURLToFile(
651                 getClass().getResource("/java/lang/Object.class"),
652                 objFile1);
653 
654         final File objFile1b =
655                 new File(tempDirFile, getName() + ".object2");
656         FileUtils.copyURLToFile(
657                 getClass().getResource("/java/lang/Object.class"),
658                 objFile1b);
659 
660         final File objFile2 =
661                 new File(tempDirFile, getName() + ".collection");
662         FileUtils.copyURLToFile(
663                 getClass().getResource("/java/util/Collection.class"),
664                 objFile2);
665 
666         assertFalse(FileUtils.contentEquals(objFile1, objFile2));
667         assertFalse(FileUtils.contentEquals(objFile1b, objFile2));
668         assertTrue(FileUtils.contentEquals(objFile1, objFile1b));
669 
670         assertTrue(FileUtils.contentEquals(objFile1, objFile1));
671         assertTrue(FileUtils.contentEquals(objFile1b, objFile1b));
672         assertTrue(FileUtils.contentEquals(objFile2, objFile2));
673 
674         // Equal files
675         file.createNewFile();
676         file2.createNewFile();
677         assertTrue(FileUtils.contentEquals(file, file));
678         assertTrue(FileUtils.contentEquals(file, file2));
679     }
680 
681     @Test
682     public void testContentEqualsIgnoreEOL() throws Exception {
683         // Non-existent files
684         final File file1 = new File(tempDirFile, getName());
685         final File file2 = new File(tempDirFile, getName() + "2");
686         assertTrue(FileUtils.contentEqualsIgnoreEOL(null, null, null));
687         assertFalse(FileUtils.contentEqualsIgnoreEOL(null, file1, null));
688         assertFalse(FileUtils.contentEqualsIgnoreEOL(file1, null, null));
689         // both don't  exist
690         assertTrue(FileUtils.contentEqualsIgnoreEOL(file1, file1, null));
691         assertTrue(FileUtils.contentEqualsIgnoreEOL(file1, file2, null));
692         assertTrue(FileUtils.contentEqualsIgnoreEOL(file2, file2, null));
693         assertTrue(FileUtils.contentEqualsIgnoreEOL(file2, file1, null));
694 
695         // Directories
696         assertThrows(IllegalArgumentException.class,
697             () -> FileUtils.contentEqualsIgnoreEOL(tempDirFile, tempDirFile, null));
698 
699         // Different files
700         final File tfile1 = new File(tempDirFile, getName() + ".txt1");
701         FileUtils.write(tfile1, "123\r");
702 
703         final File tfile2 = new File(tempDirFile, getName() + ".txt2");
704         FileUtils.write(tfile2, "123\n");
705 
706         final File tfile3 = new File(tempDirFile, getName() + ".collection");
707         FileUtils.write(tfile3, "123\r\n2");
708 
709         assertTrue(FileUtils.contentEqualsIgnoreEOL(tfile1, tfile1, null));
710         assertTrue(FileUtils.contentEqualsIgnoreEOL(tfile2, tfile2, null));
711         assertTrue(FileUtils.contentEqualsIgnoreEOL(tfile3, tfile3, null));
712 
713         assertTrue(FileUtils.contentEqualsIgnoreEOL(tfile1, tfile2, null));
714         assertFalse(FileUtils.contentEqualsIgnoreEOL(tfile1, tfile3, null));
715         assertFalse(FileUtils.contentEqualsIgnoreEOL(tfile2, tfile3, null));
716 
717         final URL urlCR = getClass().getResource("FileUtilsTestDataCR.dat");
718         assertNotNull(urlCR);
719         final File cr = new File(urlCR.toURI());
720         assertTrue(cr.exists());
721 
722         final URL urlCRLF = getClass().getResource("FileUtilsTestDataCRLF.dat");
723         assertNotNull(urlCRLF);
724         final File crlf = new File(urlCRLF.toURI());
725         assertTrue(crlf.exists());
726 
727         final URL urlLF = getClass().getResource("FileUtilsTestDataLF.dat");
728         assertNotNull(urlLF);
729         final File lf = new File(urlLF.toURI());
730         assertTrue(lf.exists());
731 
732         assertTrue(FileUtils.contentEqualsIgnoreEOL(cr, cr, null));
733         assertTrue(FileUtils.contentEqualsIgnoreEOL(crlf, crlf, null));
734         assertTrue(FileUtils.contentEqualsIgnoreEOL(lf, lf, null));
735 
736         assertTrue(FileUtils.contentEqualsIgnoreEOL(cr, crlf, null));
737         assertTrue(FileUtils.contentEqualsIgnoreEOL(cr, lf, null));
738         assertTrue(FileUtils.contentEqualsIgnoreEOL(crlf, lf, null));
739 
740         // Check the files behave OK when EOL is not ignored
741         assertTrue(FileUtils.contentEquals(cr, cr));
742         assertTrue(FileUtils.contentEquals(crlf, crlf));
743         assertTrue(FileUtils.contentEquals(lf, lf));
744 
745         assertFalse(FileUtils.contentEquals(cr, crlf));
746         assertFalse(FileUtils.contentEquals(cr, lf));
747         assertFalse(FileUtils.contentEquals(crlf, lf));
748 
749         // Equal files
750         file1.createNewFile();
751         file2.createNewFile();
752         assertTrue(FileUtils.contentEqualsIgnoreEOL(file1, file1, null));
753         assertTrue(FileUtils.contentEqualsIgnoreEOL(file1, file2, null));
754     }
755 
756     @Test
757     public void testCopyDirectoryExceptions() {
758         //
759         // NullPointerException
760         assertThrows(NullPointerException.class, () -> FileUtils.copyDirectory(null, null));
761         assertThrows(NullPointerException.class, () -> FileUtils.copyDirectory(null, testFile1));
762         assertThrows(NullPointerException.class, () -> FileUtils.copyDirectory(testFile1, null));
763         assertThrows(NullPointerException.class, () -> FileUtils.copyDirectory(null, new File("a")));
764         //
765         // IllegalArgumentException
766         assertThrows(IllegalArgumentException.class, () -> FileUtils.copyDirectory(testFile1, new File("a")));
767         assertThrows(IllegalArgumentException.class, () -> FileUtils.copyDirectory(testFile1, new File("a")));
768         assertThrows(IllegalArgumentException.class, () -> FileUtils.copyDirectory(tempDirFile, tempDirFile));
769         //
770         // IOException
771         assertThrows(IOException.class, () -> FileUtils.copyDirectory(new File("doesnt-exist"), new File("a")));
772         assertThrows(IllegalArgumentException.class, () -> FileUtils.copyDirectory(tempDirFile, testFile1));
773     }
774 
775     @Test
776     public void testCopyDirectoryFiltered() throws IOException {
777         final File grandParentDir = new File(tempDirFile, "grandparent");
778         final File parentDir = new File(grandParentDir, "parent");
779         final File childDir = new File(parentDir, "child");
780         createFilesForTestCopyDirectory(grandParentDir, parentDir, childDir);
781 
782         final NameFileFilter filter = new NameFileFilter("parent", "child", "file3.txt");
783         final File destDir = new File(tempDirFile, "copydest");
784 
785         FileUtils.copyDirectory(grandParentDir, destDir, filter);
786         final List<File> files = LIST_WALKER.list(destDir);
787         assertEquals(3, files.size());
788         assertEquals("parent", files.get(0).getName());
789         assertEquals("child", files.get(1).getName());
790         assertEquals("file3.txt", files.get(2).getName());
791     }
792 
793 //   @Test public void testToURLs2() throws Exception {
794 //        File[] files = new File[] {
795 //            new File(temporaryFolder, "file1.txt"),
796 //            null,
797 //        };
798 //        URL[] urls = FileUtils.toURLs(files);
799 //
800 //        assertEquals(files.length, urls.length);
801 //        assertTrue(urls[0].toExternalForm().startsWith("file:"));
802 //        assertTrue(urls[0].toExternalForm().indexOf("file1.txt") > 0);
803 //        assertEquals(null, urls[1]);
804 //    }
805 //
806 //   @Test public void testToURLs3() throws Exception {
807 //        File[] files = null;
808 //        URL[] urls = FileUtils.toURLs(files);
809 //
810 //        assertEquals(0, urls.length);
811 //    }
812 
813     @Test
814     public void testCopyDirectoryPreserveDates() throws Exception {
815         final File source = new File(tempDirFile, "source");
816         final File sourceDirectory = new File(source, "directory");
817         final File sourceFile = new File(sourceDirectory, "hello.txt");
818 
819         // Prepare source data
820         source.mkdirs();
821         sourceDirectory.mkdir();
822         FileUtils.writeStringToFile(sourceFile, "HELLO WORLD", "UTF8");
823         // Set dates in reverse order to avoid overwriting previous values
824         // Also, use full seconds (arguments are in ms) close to today
825         // but still highly unlikely to occur in the real world
826         assertTrue(setLastModifiedMillis(sourceFile, DATE3));
827         assertTrue(setLastModifiedMillis(sourceDirectory, DATE2));
828         assertTrue(setLastModifiedMillis(source, DATE1));
829 
830         final File target = new File(tempDirFile, "target");
831         final File targetDirectory = new File(target, "directory");
832         final File targetFile = new File(targetDirectory, "hello.txt");
833 
834         // Test with preserveFileDate disabled
835         // On Windows, the last modified time is copied by default.
836         FileUtils.copyDirectory(source, target, false);
837         assertNotEquals(DATE1, getLastModifiedMillis(target));
838         assertNotEquals(DATE2, getLastModifiedMillis(targetDirectory));
839         if (!SystemUtils.IS_OS_WINDOWS) {
840             assertNotEquals(DATE3, getLastModifiedMillis(targetFile));
841         }
842 
843         // Test permission of copied file match destination folder
844         if (!SystemUtils.IS_OS_WINDOWS) {
845             final Set<PosixFilePermission> parentPerms = Files.getPosixFilePermissions(target.getParentFile().toPath());
846             final Set<PosixFilePermission> targetPerms = Files.getPosixFilePermissions(target.toPath());
847             assertEquals(parentPerms, targetPerms);
848         } else {
849             final AclFileAttributeView parentView = Files.getFileAttributeView(target.getParentFile().toPath(), AclFileAttributeView.class);
850             final AclFileAttributeView targetView = Files.getFileAttributeView(target.toPath(), AclFileAttributeView.class);
851             assertEquals(parentView.getAcl(), targetView.getAcl());
852         }
853 
854         FileUtils.deleteDirectory(target);
855 
856         // Test with preserveFileDate enabled
857         FileUtils.copyDirectory(source, target, true);
858         assertEquals(DATE1, getLastModifiedMillis(target));
859         assertEquals(DATE2, getLastModifiedMillis(targetDirectory));
860         assertEquals(DATE3, getLastModifiedMillis(targetFile));
861         FileUtils.deleteDirectory(target);
862 
863         // also if the target directory already exists (IO-190)
864         target.mkdirs();
865         FileUtils.copyDirectory(source, target, true);
866         assertEquals(DATE1, getLastModifiedMillis(target));
867         assertEquals(DATE2, getLastModifiedMillis(targetDirectory));
868         assertEquals(DATE3, getLastModifiedMillis(targetFile));
869         FileUtils.deleteDirectory(target);
870 
871         // also if the target subdirectory already exists (IO-190)
872         targetDirectory.mkdirs();
873         FileUtils.copyDirectory(source, target, true);
874         assertEquals(DATE1, getLastModifiedMillis(target));
875         assertEquals(DATE2, getLastModifiedMillis(targetDirectory));
876         assertEquals(DATE3, getLastModifiedMillis(targetFile));
877         FileUtils.deleteDirectory(target);
878     }
879 
880     /** Tests IO-141 */
881     @Test
882     public void testCopyDirectoryToChild() throws IOException {
883         final File grandParentDir = new File(tempDirFile, "grandparent");
884         final File parentDir = new File(grandParentDir, "parent");
885         final File childDir = new File(parentDir, "child");
886         createFilesForTestCopyDirectory(grandParentDir, parentDir, childDir);
887 
888         final long expectedCount = LIST_WALKER.list(grandParentDir).size() + LIST_WALKER.list(parentDir).size();
889         final long expectedSize = FileUtils.sizeOfDirectory(grandParentDir) + FileUtils.sizeOfDirectory(parentDir);
890         FileUtils.copyDirectory(parentDir, childDir);
891         assertEquals(expectedCount, LIST_WALKER.list(grandParentDir).size());
892         assertEquals(expectedSize, FileUtils.sizeOfDirectory(grandParentDir));
893         assertTrue(expectedCount > 0, "Count > 0");
894         assertTrue(expectedSize > 0, "Size > 0");
895     }
896 
897     @Test
898     public void testCopyDirectoryToDirectory_NonExistingDest() throws Exception {
899         if (!testFile1.getParentFile().exists()) {
900             fail("Cannot create file " + testFile1
901                     + " as the parent directory does not exist");
902         }
903         try (final OutputStream output1 = new BufferedOutputStream(Files.newOutputStream(testFile1.toPath()))) {
904             TestUtils.generateTestData(output1, 1234);
905         }
906         if (!testFile2.getParentFile().exists()) {
907             fail("Cannot create file " + testFile2
908                     + " as the parent directory does not exist");
909         }
910         try (final OutputStream output = new BufferedOutputStream(Files.newOutputStream(testFile2.toPath()))) {
911             TestUtils.generateTestData(output, 4321);
912         }
913         final File srcDir = tempDirFile;
914         final File subDir = new File(srcDir, "sub");
915         subDir.mkdir();
916         final File subFile = new File(subDir, "A.txt");
917         FileUtils.writeStringToFile(subFile, "HELLO WORLD", "UTF8");
918         final File destDir = new File(FileUtils.getTempDirectoryPath(), "tmp-FileUtilsTestCase");
919         FileUtils.deleteDirectory(destDir);
920         final File actualDestDir = new File(destDir, srcDir.getName());
921 
922         FileUtils.copyDirectoryToDirectory(srcDir, destDir);
923 
924         assertTrue(destDir.exists(), "Check exists");
925         assertTrue(actualDestDir.exists(), "Check exists");
926         final long srcSize = FileUtils.sizeOfDirectory(srcDir);
927         assertTrue(srcSize > 0, "Size > 0");
928         assertEquals(srcSize, FileUtils.sizeOfDirectory(actualDestDir), "Check size");
929         assertTrue(new File(actualDestDir, "sub/A.txt").exists());
930         FileUtils.deleteDirectory(destDir);
931     }
932 
933     @Test
934     public void testCopyDirectoryToExistingDest() throws Exception {
935         if (!testFile1.getParentFile().exists()) {
936             fail("Cannot create file " + testFile1
937                     + " as the parent directory does not exist");
938         }
939         try (final OutputStream output1 = new BufferedOutputStream(Files.newOutputStream(testFile1.toPath()))) {
940             TestUtils.generateTestData(output1, 1234);
941         }
942         if (!testFile2.getParentFile().exists()) {
943             fail("Cannot create file " + testFile2
944                     + " as the parent directory does not exist");
945         }
946         try (final OutputStream output = new BufferedOutputStream(Files.newOutputStream(testFile2.toPath()))) {
947             TestUtils.generateTestData(output, 4321);
948         }
949         final File srcDir = tempDirFile;
950         final File subDir = new File(srcDir, "sub");
951         subDir.mkdir();
952         final File subFile = new File(subDir, "A.txt");
953         FileUtils.writeStringToFile(subFile, "HELLO WORLD", "UTF8");
954         final File destDir = new File(System.getProperty("java.io.tmpdir"), "tmp-FileUtilsTestCase");
955         FileUtils.deleteDirectory(destDir);
956         destDir.mkdirs();
957 
958         FileUtils.copyDirectory(srcDir, destDir);
959 
960         final long srcSize = FileUtils.sizeOfDirectory(srcDir);
961         assertTrue(srcSize > 0, "Size > 0");
962         assertEquals(srcSize, FileUtils.sizeOfDirectory(destDir));
963         assertTrue(new File(destDir, "sub/A.txt").exists());
964     }
965 
966     /** Test IO-141 */
967     @Test
968     public void testCopyDirectoryToGrandChild() throws IOException {
969         final File grandParentDir = new File(tempDirFile, "grandparent");
970         final File parentDir = new File(grandParentDir, "parent");
971         final File childDir = new File(parentDir, "child");
972         createFilesForTestCopyDirectory(grandParentDir, parentDir, childDir);
973 
974         final long expectedCount = LIST_WALKER.list(grandParentDir).size() * 2;
975         final long expectedSize = FileUtils.sizeOfDirectory(grandParentDir) * 2;
976         FileUtils.copyDirectory(grandParentDir, childDir);
977         assertEquals(expectedCount, LIST_WALKER.list(grandParentDir).size());
978         assertEquals(expectedSize, FileUtils.sizeOfDirectory(grandParentDir));
979         assertTrue(expectedSize > 0, "Size > 0");
980     }
981 
982     /** Tests IO-217 FileUtils.copyDirectoryToDirectory makes infinite loops */
983     @Test
984     public void testCopyDirectoryToItself() throws Exception {
985         final File dir = new File(tempDirFile, "itself");
986         dir.mkdirs();
987         FileUtils.copyDirectoryToDirectory(dir, dir);
988         assertEquals(1, LIST_WALKER.list(dir).size());
989     }
990 
991     @Test
992     public void testCopyDirectoryToNonExistingDest() throws Exception {
993         if (!testFile1.getParentFile().exists()) {
994             fail("Cannot create file " + testFile1
995                     + " as the parent directory does not exist");
996         }
997         try (final OutputStream output1 = new BufferedOutputStream(Files.newOutputStream(testFile1.toPath()))) {
998             TestUtils.generateTestData(output1, 1234);
999         }
1000         if (!testFile2.getParentFile().exists()) {
1001             fail("Cannot create file " + testFile2
1002                     + " as the parent directory does not exist");
1003         }
1004         try (final OutputStream output = new BufferedOutputStream(Files.newOutputStream(testFile2.toPath()));) {
1005             TestUtils.generateTestData(output, 4321);
1006         }
1007         final File srcDir = tempDirFile;
1008         final File subDir = new File(srcDir, "sub");
1009         subDir.mkdir();
1010         final File subFile = new File(subDir, "A.txt");
1011         FileUtils.writeStringToFile(subFile, "HELLO WORLD", "UTF8");
1012         final File destDir = new File(FileUtils.getTempDirectoryPath(), "tmp-FileUtilsTestCase");
1013         FileUtils.deleteDirectory(destDir);
1014 
1015         FileUtils.copyDirectory(srcDir, destDir);
1016 
1017         assertTrue(destDir.exists(), "Check exists");
1018         final long sizeOfSrcDirectory = FileUtils.sizeOfDirectory(srcDir);
1019         assertTrue(sizeOfSrcDirectory > 0, "Size > 0");
1020         assertEquals(sizeOfSrcDirectory, FileUtils.sizeOfDirectory(destDir), "Check size");
1021         assertTrue(new File(destDir, "sub/A.txt").exists());
1022         FileUtils.deleteDirectory(destDir);
1023     }
1024 
1025     /**
1026      * Test for https://github.com/apache/commons-io/pull/371. The dir name 'par' is a substring of
1027      * the dir name 'parent' which is the parent of the 'parent/child' dir.
1028      */
1029     @Test
1030     public void testCopyDirectoryWithPotentialFalsePartialMatch() throws IOException {
1031         final File grandParentDir = new File(tempDirFile, "grandparent");
1032         final File parentDir = new File(grandParentDir, "parent");
1033         final File parDir = new File(grandParentDir, "par");
1034         final File childDir = new File(parentDir, "child");
1035         createFilesForTestCopyDirectory(grandParentDir, parDir, childDir);
1036 
1037         final List<File> initFiles = LIST_WALKER.list(grandParentDir);
1038         final List<File> parFiles = LIST_WALKER.list(parDir);
1039         final long expectedCount = initFiles.size() + parFiles.size();
1040         final long expectedSize = FileUtils.sizeOfDirectory(grandParentDir) + FileUtils.sizeOfDirectory(parDir);
1041         FileUtils.copyDirectory(parDir, childDir);
1042         final List<File> latestFiles = LIST_WALKER.list(grandParentDir);
1043         assertEquals(expectedCount, latestFiles.size());
1044         assertEquals(expectedSize, FileUtils.sizeOfDirectory(grandParentDir));
1045         assertTrue(expectedCount > 0, "Count > 0");
1046         assertTrue(expectedSize > 0, "Size > 0");
1047         final Set<String> initFilePaths = getFilePathSet(initFiles);
1048         final Set<String> newFilePaths = getFilePathSet(latestFiles);
1049         newFilePaths.removeAll(initFilePaths);
1050         assertEquals(parFiles.size(), newFilePaths.size());
1051     }
1052 
1053     @Test
1054     public void testCopyFile1() throws Exception {
1055         final File destination = new File(tempDirFile, "copy1.txt");
1056 
1057         backDateFile10Minutes(testFile1); // set test file back 10 minutes
1058 
1059         FileUtils.copyFile(testFile1, destination);
1060         assertTrue(destination.exists(), "Check Exist");
1061         assertEquals(testFile1Size, destination.length(), "Check Full copy");
1062         assertEquals(getLastModifiedMillis(testFile1), getLastModifiedMillis(destination), "Check last modified date preserved");
1063     }
1064 
1065     @Test
1066     public void testCopyFile1ToDir() throws Exception {
1067         final File directory = new File(tempDirFile, "subdir");
1068         if (!directory.exists()) {
1069             directory.mkdirs();
1070         }
1071         final File destination = new File(directory, testFile1.getName());
1072 
1073         backDateFile10Minutes(testFile1);
1074 
1075         FileUtils.copyFileToDirectory(testFile1, directory);
1076         assertTrue(destination.exists(), "Check Exist");
1077         assertEquals(testFile1Size, destination.length(), "Check Full copy");
1078         assertEquals(FileUtils.lastModified(testFile1), FileUtils.lastModified(destination), "Check last modified date preserved");
1079 
1080         assertThrows(IllegalArgumentException.class, () -> FileUtils.copyFileToDirectory(destination, directory),
1081             "Should not be able to copy a file into the same directory as itself");
1082     }
1083 
1084     @Test
1085     public void testCopyFile2() throws Exception {
1086         final File destination = new File(tempDirFile, "copy2.txt");
1087 
1088         backDateFile10Minutes(testFile1); // set test file back 10 minutes
1089 
1090         FileUtils.copyFile(testFile1, destination);
1091         assertTrue(destination.exists(), "Check Exist");
1092         assertEquals(testFile2Size, destination.length(), "Check Full copy");
1093         assertEquals(getLastModifiedMillis(testFile1) , getLastModifiedMillis(destination), "Check last modified date preserved");
1094     }
1095 
1096     @Test
1097     public void testCopyFile2ToDir() throws Exception {
1098         final File directory = new File(tempDirFile, "subdir");
1099         if (!directory.exists()) {
1100             directory.mkdirs();
1101         }
1102         final File destination = new File(directory, testFile1.getName());
1103 
1104         backDateFile10Minutes(testFile1);
1105 
1106         FileUtils.copyFileToDirectory(testFile1, directory);
1107         assertTrue(destination.exists(), "Check Exist");
1108         assertEquals(testFile2Size, destination.length(), "Check Full copy");
1109         assertEquals(FileUtils.lastModified(testFile1), FileUtils.lastModified(destination), "Check last modified date preserved");
1110     }
1111 
1112     @Test
1113     public void testCopyFile2WithoutFileDatePreservation() throws Exception {
1114         final File destFile = new File(tempDirFile, "copy2.txt");
1115 
1116         backDateFile10Minutes(testFile1); // set test file back 10 minutes
1117 
1118         // destination file time should not be less than this (allowing for granularity)
1119         final long nowMillis = System.currentTimeMillis() - 1000L;
1120         // On Windows, the last modified time is copied by default.
1121         FileUtils.copyFile(testFile1, destFile, false);
1122         assertTrue(destFile.exists(), "Check Exist");
1123         assertEquals(testFile1Size, destFile.length(), "Check Full copy");
1124         final long destLastModMillis = getLastModifiedMillis(destFile);
1125         final long unexpectedMillis = getLastModifiedMillis(testFile1);
1126         if (!SystemUtils.IS_OS_WINDOWS) {
1127             final long deltaMillis = destLastModMillis - unexpectedMillis;
1128             assertNotEquals(unexpectedMillis, destLastModMillis,
1129                 "Check last modified date not same as input, delta " + deltaMillis);
1130             assertTrue(destLastModMillis > nowMillis,
1131                 destLastModMillis + " > " + nowMillis + " (delta " + deltaMillis + ")");
1132         }
1133     }
1134 
1135     @Test
1136     @Disabled
1137     public void testCopyFileLarge() throws Exception {
1138 
1139         final File largeFile = new File(tempDirFile, "large.txt");
1140         final File destination = new File(tempDirFile, "copylarge.txt");
1141 
1142         System.out.println("START:   " + new java.util.Date());
1143         if (!largeFile.getParentFile().exists()) {
1144             fail("Cannot create file " + largeFile
1145                     + " as the parent directory does not exist");
1146         }
1147         try (final OutputStream output = new BufferedOutputStream(Files.newOutputStream(largeFile.toPath()))) {
1148             TestUtils.generateTestData(output, FileUtils.ONE_GB);
1149         }
1150         System.out.println("CREATED: " + new java.util.Date());
1151         FileUtils.copyFile(largeFile, destination);
1152         System.out.println("COPIED:  " + new java.util.Date());
1153 
1154         assertTrue(destination.exists(), "Check Exist");
1155         assertEquals(largeFile.length(), destination.length(), "Check Full copy");
1156     }
1157 
1158     @Test
1159     public void testCopyFileToOutputStream() throws Exception {
1160         final ByteArrayOutputStream destination = new ByteArrayOutputStream();
1161         FileUtils.copyFile(testFile1, destination);
1162         assertEquals(testFile1Size, destination.size(), "Check Full copy size");
1163         final byte[] expected = FileUtils.readFileToByteArray(testFile1);
1164         assertArrayEquals(expected, destination.toByteArray(), "Check Full copy");
1165     }
1166 
1167     @Test
1168     public void testCopyToDirectoryWithDirectory() throws IOException {
1169         final File destDirectory = new File(tempDirFile, "destination");
1170         if (!destDirectory.exists()) {
1171             destDirectory.mkdirs();
1172         }
1173 
1174         // Create a test directory
1175         final File inputDirectory = new File(tempDirFile, "input");
1176         if (!inputDirectory.exists()) {
1177             inputDirectory.mkdirs();
1178         }
1179         final File outputDirDestination = new File(destDirectory, inputDirectory.getName());
1180         FileUtils.copyToDirectory(testFile1, inputDirectory);
1181         final File destFile1 = new File(outputDirDestination, testFile1.getName());
1182         FileUtils.copyToDirectory(testFile2, inputDirectory);
1183         final File destFile2 = new File(outputDirDestination, testFile2.getName());
1184 
1185         FileUtils.copyToDirectory(inputDirectory, destDirectory);
1186 
1187         // Check the directory was created
1188         assertTrue(outputDirDestination.exists(), "Check Exists");
1189         assertTrue(outputDirDestination.isDirectory(), "Check Directory");
1190 
1191         // Check each file
1192         assertTrue(destFile1.exists(), "Check Exists");
1193         assertEquals(testFile1Size, destFile1.length(), "Check Full Copy");
1194         assertTrue(destFile2.exists(), "Check Exists");
1195         assertEquals(testFile2Size, destFile2.length(), "Check Full Copy");
1196     }
1197 
1198     @Test
1199     public void testCopyToDirectoryWithFile() throws IOException {
1200         final File directory = new File(tempDirFile, "subdir");
1201         if (!directory.exists()) {
1202             directory.mkdirs();
1203         }
1204         final File destination = new File(directory, testFile1.getName());
1205 
1206         FileUtils.copyToDirectory(testFile1, directory);
1207         assertTrue(destination.exists(), "Check Exists");
1208         assertEquals(testFile1Size, destination.length(), "Check Full Copy");
1209     }
1210 
1211     @Test
1212     public void testCopyToDirectoryWithFileSourceDoesNotExist() {
1213         assertThrows(IOException.class,
1214                 () -> FileUtils.copyToDirectory(new File(tempDirFile, "doesNotExists"), tempDirFile));
1215     }
1216 
1217     @Test
1218     public void testCopyToDirectoryWithFileSourceIsNull() {
1219         assertThrows(NullPointerException.class, () -> FileUtils.copyToDirectory((File) null, tempDirFile));
1220     }
1221 
1222     @Test
1223     public void testCopyToDirectoryWithIterable() throws IOException {
1224         final File directory = new File(tempDirFile, "subdir");
1225         if (!directory.exists()) {
1226             directory.mkdirs();
1227         }
1228 
1229         final List<File> input = new ArrayList<>();
1230         input.add(testFile1);
1231         input.add(testFile2);
1232 
1233         final File destFile1 = new File(directory, testFile1.getName());
1234         final File destFile2 = new File(directory, testFile2.getName());
1235 
1236         FileUtils.copyToDirectory(input, directory);
1237         // Check each file
1238         assertTrue(destFile1.exists(), "Check Exists");
1239         assertEquals(testFile1Size, destFile1.length(), "Check Full Copy");
1240         assertTrue(destFile2.exists(), "Check Exists");
1241         assertEquals(testFile2Size, destFile2.length(), "Check Full Copy");
1242     }
1243 
1244     @Test
1245     public void testCopyToDirectoryWithIterableSourceDoesNotExist() {
1246         assertThrows(IOException.class,
1247                 () -> FileUtils.copyToDirectory(Collections.singleton(new File(tempDirFile, "doesNotExists")),
1248                         tempDirFile));
1249     }
1250 
1251     @Test
1252     public void testCopyToDirectoryWithIterableSourceIsNull() {
1253         assertThrows(NullPointerException.class, () -> FileUtils.copyToDirectory((List<File>) null, tempDirFile));
1254     }
1255 
1256     @Test
1257     public void testCopyToSelf() throws Exception {
1258         final File destination = new File(tempDirFile, "copy3.txt");
1259         //Prepare a test file
1260         FileUtils.copyFile(testFile1, destination);
1261         assertThrows(IllegalArgumentException.class, () -> FileUtils.copyFile(destination, destination));
1262     }
1263 
1264     @Test
1265     public void testCopyURLToFile() throws Exception {
1266         // Creates file
1267         final File file = new File(tempDirFile, getName());
1268         assertContentMatchesAfterCopyURLToFileFor("/java/lang/Object.class", file);
1269         //TODO Maybe test copy to itself like for copyFile()
1270     }
1271 
1272     @Test
1273     public void testCopyURLToFileCreatesParentDirs() throws Exception {
1274         final File file = managedTempDirPath.resolve("subdir").resolve(getName()).toFile();
1275         assertContentMatchesAfterCopyURLToFileFor("/java/lang/Object.class", file);
1276     }
1277 
1278     @Test
1279     public void testCopyURLToFileReplacesExisting() throws Exception {
1280         final File file = new File(tempDirFile, getName());
1281         assertContentMatchesAfterCopyURLToFileFor("/java/lang/Object.class", file);
1282         assertContentMatchesAfterCopyURLToFileFor("/java/lang/String.class", file);
1283     }
1284 
1285     @Test
1286     public void testCopyURLToFileWithTimeout() throws Exception {
1287         // Creates file
1288         final File file = new File(tempDirFile, "testCopyURLToFileWithTimeout");
1289 
1290         // Loads resource
1291         final String resourceName = "/java/lang/Object.class";
1292         FileUtils.copyURLToFile(getClass().getResource(resourceName), file, 500, 500);
1293 
1294         // Tests that resource was copied correctly
1295         try (InputStream fis = Files.newInputStream(file.toPath());
1296              InputStream resStream = getClass().getResourceAsStream(resourceName);) {
1297             assertTrue(IOUtils.contentEquals(resStream, fis), "Content is not equal.");
1298         }
1299         //TODO Maybe test copy to itself like for copyFile()
1300     }
1301 
1302     /**
1303      * Tests a directory with one file of size 0.
1304      */
1305     @Test
1306     public void testCountFolders1FileSize0() {
1307         assertEquals(0, FileUtils.sizeOfDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-0").toFile()));
1308     }
1309 
1310     /**
1311      * Tests a directory with one file of size 1.
1312      */
1313     @Test
1314     public void testCountFolders1FileSize1() {
1315         assertEquals(1, FileUtils.sizeOfDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1").toFile()));
1316     }
1317 
1318     /**
1319      * Tests a directory with two subdirectories, each containing one file of size 1.
1320      */
1321     @Test
1322     public void testCountFolders2FileSize2() {
1323         assertEquals(2, FileUtils.sizeOfDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-2-file-size-2").toFile()));
1324     }
1325 
1326     /**
1327      * Tests a directory with two subdirectories, each containing one file of size 1.
1328      */
1329     @Test
1330     public void testCountFolders2FileSize4() {
1331         assertEquals(8, FileUtils.sizeOfDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-2-file-size-4").toFile()));
1332     }
1333 
1334     @Test
1335     public void testCreateParentDirectories() throws IOException {
1336         // If a directory already exists, nothing happens.
1337         FileUtils.createParentDirectories(FileUtils.current());
1338         // null is a noop
1339         FileUtils.createParentDirectories(null);
1340     }
1341 
1342     @Test
1343     public void testDecodeUrl() {
1344         assertEquals("", FileUtils.decodeUrl(""));
1345         assertEquals("foo", FileUtils.decodeUrl("foo"));
1346         assertEquals("+", FileUtils.decodeUrl("+"));
1347         assertEquals("% ", FileUtils.decodeUrl("%25%20"));
1348         assertEquals("%20", FileUtils.decodeUrl("%2520"));
1349         assertEquals("jar:file:/C:/dir/sub dir/1.0/foo-1.0.jar!/org/Bar.class", FileUtils
1350                 .decodeUrl("jar:file:/C:/dir/sub%20dir/1.0/foo-1.0.jar!/org/Bar.class"));
1351     }
1352 
1353     @Test
1354     public void testDecodeUrlEncodingUtf8() {
1355         assertEquals("\u00E4\u00F6\u00FC\u00DF", FileUtils.decodeUrl("%C3%A4%C3%B6%C3%BC%C3%9F"));
1356     }
1357 
1358     @Test
1359     public void testDecodeUrlLenient() {
1360         assertEquals(" ", FileUtils.decodeUrl(" "));
1361         assertEquals("\u00E4\u00F6\u00FC\u00DF", FileUtils.decodeUrl("\u00E4\u00F6\u00FC\u00DF"));
1362         assertEquals("%", FileUtils.decodeUrl("%"));
1363         assertEquals("% ", FileUtils.decodeUrl("%%20"));
1364         assertEquals("%2", FileUtils.decodeUrl("%2"));
1365         assertEquals("%2G", FileUtils.decodeUrl("%2G"));
1366     }
1367 
1368     @Test
1369     public void testDecodeUrlNullSafe() {
1370         assertNull(FileUtils.decodeUrl(null));
1371     }
1372 
1373     @Test
1374     public void testDelete() throws Exception {
1375         assertEquals(testFile1, FileUtils.delete(testFile1));
1376         assertThrows(IOException.class, () -> FileUtils.delete(new File("does not exist.nope")));
1377     }
1378 
1379     @Test
1380     public void testDeleteDirectoryWithNonDirectory() {
1381         assertThrows(IllegalArgumentException.class, () -> FileUtils.deleteDirectory(testFile1));
1382     }
1383 
1384     @Test
1385     public void testDeleteQuietlyDir() throws IOException {
1386         final File testDirectory = new File(tempDirFile, "testDeleteQuietlyDir");
1387         final File testFile = new File(testDirectory, "testDeleteQuietlyFile");
1388         testDirectory.mkdirs();
1389         if (!testFile.getParentFile().exists()) {
1390             fail("Cannot create file " + testFile
1391                     + " as the parent directory does not exist");
1392         }
1393         try (final OutputStream output = new BufferedOutputStream(Files.newOutputStream(testFile.toPath()))) {
1394             TestUtils.generateTestData(output, 0);
1395         }
1396 
1397         assertTrue(testDirectory.exists());
1398         assertTrue(testFile.exists());
1399         FileUtils.deleteQuietly(testDirectory);
1400         assertFalse(testDirectory.exists(), "Check No Exist");
1401         assertFalse(testFile.exists(), "Check No Exist");
1402     }
1403 
1404     @Test
1405     public void testDeleteQuietlyFile() throws IOException {
1406         final File testFile = new File(tempDirFile, "testDeleteQuietlyFile");
1407         if (!testFile.getParentFile().exists()) {
1408             fail("Cannot create file " + testFile
1409                     + " as the parent directory does not exist");
1410         }
1411         try (final OutputStream output = new BufferedOutputStream(Files.newOutputStream(testFile.toPath()))) {
1412             TestUtils.generateTestData(output, 0);
1413         }
1414 
1415         assertTrue(testFile.exists());
1416         FileUtils.deleteQuietly(testFile);
1417         assertFalse(testFile.exists(), "Check No Exist");
1418     }
1419 
1420     @Test
1421     public void testDeleteQuietlyForNull() {
1422         FileUtils.deleteQuietly(null);
1423     }
1424 
1425     @Test
1426     public void testDeleteQuietlyNonExistent() {
1427         final File testFile = new File("testDeleteQuietlyNonExistent");
1428         assertFalse(testFile.exists());
1429         FileUtils.deleteQuietly(testFile);
1430     }
1431 
1432     /**
1433      * Tests the FileUtils implementation.
1434      */
1435     @Test
1436     public void testFileUtils() throws Exception {
1437         // Loads file from classpath
1438         final File file1 = new File(tempDirFile, "test.txt");
1439         final String fileName = file1.getAbsolutePath();
1440 
1441         //Create test file on-the-fly (used to be in CVS)
1442         try (OutputStream out = Files.newOutputStream(file1.toPath())) {
1443             out.write("This is a test".getBytes(StandardCharsets.UTF_8));
1444         }
1445 
1446         final File file2 = new File(tempDirFile, "test2.txt");
1447 
1448         FileUtils.writeStringToFile(file2, fileName, UTF_8);
1449         assertTrue(file2.exists());
1450         assertTrue(file2.length() > 0);
1451 
1452         final String file2contents = FileUtils.readFileToString(file2, UTF_8);
1453         assertEquals(fileName, file2contents, "Second file's contents correct");
1454 
1455         assertTrue(file2.delete());
1456 
1457         final String contents = FileUtils.readFileToString(new File(fileName), UTF_8);
1458         assertEquals("This is a test", contents, "FileUtils.fileRead()");
1459 
1460     }
1461 
1462     @Test
1463     public void testForceDeleteAFile1() throws Exception {
1464         final File destination = new File(tempDirFile, "copy1.txt");
1465         destination.createNewFile();
1466         assertTrue(destination.exists(), "Copy1.txt doesn't exist to delete");
1467         FileUtils.forceDelete(destination);
1468         assertFalse(destination.exists(), "Check No Exist");
1469     }
1470 
1471     @Test
1472     public void testForceDeleteAFile2() throws Exception {
1473         final File destination = new File(tempDirFile, "copy2.txt");
1474         destination.createNewFile();
1475         assertTrue(destination.exists(), "Copy2.txt doesn't exist to delete");
1476         FileUtils.forceDelete(destination);
1477         assertFalse(destination.exists(), "Check No Exist");
1478     }
1479 
1480     @Test
1481     public void testForceDeleteAFile3() {
1482         final File destination = new File(tempDirFile, "no_such_file");
1483         assertFalse(destination.exists(), "Check No Exist");
1484         assertThrows(IOException.class, () -> FileUtils.forceDelete(destination));
1485 
1486     }
1487 
1488     @Test
1489     public void testForceDeleteDir() throws Exception {
1490         final File testDirectory = tempDirFile;
1491         assertTrue(testDirectory.exists(), "TestDirectory must exist");
1492         FileUtils.forceDelete(testDirectory);
1493         assertFalse(testDirectory.exists(), "TestDirectory must not exist");
1494     }
1495 
1496     @Test
1497     public void testForceDeleteReadOnlyFile() throws Exception {
1498         try (TempFile destination = TempFile.create("test-", ".txt")) {
1499             final File file = destination.toFile();
1500             assertTrue(file.setReadOnly());
1501             assertTrue(file.canRead());
1502             assertFalse(file.canWrite());
1503             // sanity check that File.delete() deletes read-only files.
1504             assertTrue(file.delete());
1505         }
1506         try (TempFile destination = TempFile.create("test-", ".txt")) {
1507             final File file = destination.toFile();
1508             // real test
1509             assertTrue(file.setReadOnly());
1510             assertTrue(file.canRead());
1511             assertFalse(file.canWrite());
1512             assertTrue(file.exists(), "File doesn't exist to delete");
1513             FileUtils.forceDelete(file);
1514             assertFalse(file.exists(), "Check deletion");
1515         }
1516     }
1517 
1518     @Test
1519     public void testForceMkdir() throws Exception {
1520         // Tests with existing directory
1521         FileUtils.forceMkdir(tempDirFile);
1522 
1523         // Creates test file
1524         final File testFile = new File(tempDirFile, getName());
1525         testFile.createNewFile();
1526         assertTrue(testFile.exists(), "Test file does not exist.");
1527 
1528         // Tests with existing file
1529         assertThrows(IOException.class, () -> FileUtils.forceMkdir(testFile));
1530 
1531         testFile.delete();
1532 
1533         // Tests with non-existent directory
1534         FileUtils.forceMkdir(testFile);
1535         assertTrue(testFile.exists(), "Directory was not created.");
1536 
1537         // noop
1538         FileUtils.forceMkdir(null);
1539     }
1540 
1541     @Test
1542     public void testForceMkdirParent() throws Exception {
1543         // Tests with existing directory
1544         assertTrue(tempDirFile.exists());
1545         final File testParentDir = new File(tempDirFile, "testForceMkdirParent");
1546         testParentDir.delete();
1547         assertFalse(testParentDir.exists());
1548         final File testFile = new File(testParentDir, "test.txt");
1549         assertFalse(testParentDir.exists());
1550         assertFalse(testFile.exists());
1551         // Create
1552         FileUtils.forceMkdirParent(testFile);
1553         assertTrue(testParentDir.exists());
1554         assertFalse(testFile.exists());
1555         // Again
1556         FileUtils.forceMkdirParent(testFile);
1557         assertTrue(testParentDir.exists());
1558         assertFalse(testFile.exists());
1559     }
1560 
1561     @Test
1562     public void testGetFile() {
1563         final File expected_A = new File("src");
1564         final File expected_B = new File(expected_A, "main");
1565         final File expected_C = new File(expected_B, "java");
1566         assertEquals(expected_A, FileUtils.getFile("src"), "A");
1567         assertEquals(expected_B, FileUtils.getFile("src", "main"), "B");
1568         assertEquals(expected_C, FileUtils.getFile("src", "main", "java"), "C");
1569         assertThrows(NullPointerException.class, () -> FileUtils.getFile((String[]) null));
1570 
1571     }
1572 
1573     @Test
1574     public void testGetFile_Parent() {
1575         final File parent = new File("parent");
1576         final File expected_A = new File(parent, "src");
1577         final File expected_B = new File(expected_A, "main");
1578         final File expected_C = new File(expected_B, "java");
1579         assertEquals(expected_A, FileUtils.getFile(parent, "src"), "A");
1580         assertEquals(expected_B, FileUtils.getFile(parent, "src", "main"), "B");
1581         assertEquals(expected_C, FileUtils.getFile(parent, "src", "main", "java"), "C");
1582         assertThrows(NullPointerException.class, () -> FileUtils.getFile(parent, (String[]) null));
1583         assertThrows(NullPointerException.class, () -> FileUtils.getFile((File) null, "src"));
1584     }
1585 
1586     @Test
1587     public void testGetTempDirectory() {
1588         final File tempDirectory = new File(FileUtils.getTempDirectoryPath());
1589         assertEquals(tempDirectory, FileUtils.getTempDirectory());
1590     }
1591 
1592     @Test
1593     public void testGetTempDirectoryPath() {
1594         assertEquals(System.getProperty("java.io.tmpdir"), FileUtils.getTempDirectoryPath());
1595     }
1596 
1597     @Test
1598     public void testGetUserDirectory() {
1599         final File userDirectory = new File(System.getProperty("user.home"));
1600         assertEquals(userDirectory, FileUtils.getUserDirectory());
1601     }
1602 
1603     @Test
1604     public void testGetUserDirectoryPath() {
1605         assertEquals(System.getProperty("user.home"), FileUtils.getUserDirectoryPath());
1606     }
1607 
1608     @Test
1609     public void testIO276() throws Exception {
1610         final File dir = new File("target", "IO276");
1611         assertTrue(dir.mkdirs(), dir + " should not be present");
1612         final File file = new File(dir, "IO276.txt");
1613         assertTrue(file.createNewFile(), file + " should not be present");
1614         FileUtils.forceDeleteOnExit(dir);
1615         // If this does not work, test will fail next time (assuming target is not cleaned)
1616     }
1617 
1618     @Test
1619     public void testIO300() {
1620         final File testDirectory = tempDirFile;
1621         final File src = new File(testDirectory, "dir1");
1622         final File dest = new File(src, "dir2");
1623         assertTrue(dest.mkdirs());
1624         assertTrue(src.exists());
1625         assertThrows(IOException.class, () -> FileUtils.moveDirectoryToDirectory(src, dest, false));
1626         assertTrue(src.exists());
1627     }
1628 
1629     @Test
1630     public void testIO575() throws IOException {
1631         final Path sourceDir = Files.createTempDirectory("source-dir");
1632         final String fileName = "some-file";
1633         final Path sourceFile = Files.createFile(sourceDir.resolve(fileName));
1634 
1635         assertEquals(SystemUtils.IS_OS_WINDOWS, sourceFile.toFile().canExecute());
1636 
1637         sourceFile.toFile().setExecutable(true);
1638 
1639         assertTrue(sourceFile.toFile().canExecute());
1640 
1641         final Path destDir = Files.createTempDirectory("some-empty-destination");
1642 
1643         FileUtils.copyDirectory(sourceDir.toFile(), destDir.toFile());
1644 
1645         final Path destFile = destDir.resolve(fileName);
1646 
1647         assertTrue(destFile.toFile().exists());
1648         assertTrue(destFile.toFile().canExecute());
1649     }
1650 
1651     @Test
1652     public void testIsDirectory() throws IOException {
1653         assertFalse(FileUtils.isDirectory(null));
1654 
1655         assertTrue(FileUtils.isDirectory(tempDirFile));
1656         assertFalse(FileUtils.isDirectory(testFile1));
1657 
1658         final File tempDirAsFile;
1659         try (TempDirectory tempDir = TempDirectory.create(getClass().getCanonicalName())) {
1660             tempDirAsFile = tempDir.toFile();
1661             assertTrue(FileUtils.isDirectory(tempDirAsFile));
1662         }
1663         assertFalse(FileUtils.isDirectory(tempDirAsFile));
1664     }
1665 
1666     @Test
1667     public void testIsEmptyDirectory() throws IOException {
1668         try (TempDirectory tempDir = TempDirectory.create(getClass().getCanonicalName())) {
1669             final File tempDirAsFile = tempDir.toFile();
1670             Assertions.assertTrue(FileUtils.isEmptyDirectory(tempDirAsFile));
1671         }
1672         Assertions.assertFalse(FileUtils.isEmptyDirectory(PathUtilsIsEmptyTest.DIR_SIZE_1.toFile()));
1673     }
1674 
1675     @ParameterizedTest
1676     @ValueSource(longs = {1L, 100L, 1_000L, 10_000L, 100_000L, 1_000_000L})
1677     public void testIsFileNewerOlder(final long millis) throws Exception {
1678         // Files
1679         final File oldFile = new File(tempDirFile, "FileUtils-old.txt");
1680         final File refFile = new File(tempDirFile, "FileUtils-reference.txt");
1681         final File newFile = new File(tempDirFile, "FileUtils-new.txt");
1682         final File invalidFile = new File(tempDirFile, "FileUtils-invalid-file.txt");
1683         // Paths
1684         final Path oldPath = oldFile.toPath();
1685         final Path refPath = refFile.toPath();
1686         final Path newPath = newFile.toPath();
1687         // FileTimes
1688         // TODO What is wrong with Java 8 on macOS? Or is this a macOS file system issue?
1689         final long actualMillis = SystemUtils.IS_OS_MAC && SystemUtils.IS_JAVA_1_8 ? millis + 1000 : millis;
1690         final FileTime oldFileTime = FileTime.from(actualMillis * 1, TimeUnit.MILLISECONDS);
1691         final FileTime refFileTime = FileTime.from(actualMillis * 2, TimeUnit.MILLISECONDS);
1692         final FileTime testFileTime = FileTime.from(actualMillis * 3, TimeUnit.MILLISECONDS);
1693         final FileTime newFileTime = FileTime.from(actualMillis * 4, TimeUnit.MILLISECONDS);
1694 
1695         // Create fixtures
1696         try (final OutputStream output = new BufferedOutputStream(Files.newOutputStream(oldPath))) {
1697             TestUtils.generateTestData(output, 0);
1698         }
1699         Files.setLastModifiedTime(oldPath, oldFileTime);
1700 
1701         try (final OutputStream output = new BufferedOutputStream(Files.newOutputStream(refPath))) {
1702             TestUtils.generateTestData(output, 0);
1703         }
1704         Files.setLastModifiedTime(refPath, refFileTime);
1705 
1706         final Date date = new Date(testFileTime.toMillis());
1707         final long now = date.getTime();
1708         final Instant instant = date.toInstant();
1709         final ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
1710         final OffsetDateTime offsetDateTime = zonedDateTime.toOffsetDateTime();
1711         final LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
1712         final LocalDate localDate = zonedDateTime.toLocalDate();
1713         final LocalDate localDatePlusDay = localDate.plusDays(1);
1714         final LocalTime localTime0 = LocalTime.MIDNIGHT;
1715         final OffsetTime offsetTime0 = OffsetTime.of(localTime0, ZoneOffset.UTC);
1716 
1717         try (final OutputStream output = new BufferedOutputStream(Files.newOutputStream(newPath))) {
1718             TestUtils.generateTestData(output, 0);
1719         }
1720         Files.setLastModifiedTime(newPath, newFileTime);
1721 
1722         // Test
1723         assertFalse(FileUtils.isFileNewer(oldFile, refFile), "Old File - Newer - File");
1724         assertFalse(FileUtils.isFileNewer(oldFile, date), "Old File - Newer - Date");
1725         assertFalse(FileUtils.isFileNewer(oldFile, now), "Old File - Newer - Mili");
1726         assertFalse(FileUtils.isFileNewer(oldFile, instant), "Old File - Newer - Instant");
1727         assertFalse(FileUtils.isFileNewer(oldFile, zonedDateTime), "Old File - Newer - ZonedDateTime");
1728         assertFalse(FileUtils.isFileNewer(oldFile, offsetDateTime), "Old File - Newer - OffsetDateTime");
1729         assertFalse(FileUtils.isFileNewer(oldFile, localDateTime), "Old File - Newer - LocalDateTime");
1730         assertFalse(FileUtils.isFileNewer(oldFile, localDateTime, ZoneId.systemDefault()), "Old File - Newer - LocalDateTime,ZoneId");
1731         assertFalse(FileUtils.isFileNewer(oldFile, localDate), "Old File - Newer - LocalDate");
1732         assertTrue(FileUtils.isFileNewer(oldFile, localDate, localTime0), "Old File - Newer - LocalDate,LocalTime");
1733         assertTrue(FileUtils.isFileNewer(oldFile, localDate, offsetTime0), "Old File - Newer - LocalDate,OffsetTime");
1734         assertFalse(FileUtils.isFileNewer(oldFile, localDatePlusDay), "Old File - Newer - LocalDate plus one day");
1735         assertFalse(FileUtils.isFileNewer(oldFile, localDatePlusDay, localTime0), "Old File - Newer - LocalDate plus one day,LocalTime");
1736         assertFalse(FileUtils.isFileNewer(oldFile, localDatePlusDay, offsetTime0), "Old File - Newer - LocalDate plus one day,OffsetTime");
1737 
1738         assertTrue(FileUtils.isFileNewer(newFile, refFile), "New File - Newer - File");
1739         assertTrue(FileUtils.isFileNewer(newFile, date), "New File - Newer - Date");
1740         assertTrue(FileUtils.isFileNewer(newFile, now), "New File - Newer - Mili");
1741         assertTrue(FileUtils.isFileNewer(newFile, instant), "New File - Newer - Instant");
1742         assertTrue(FileUtils.isFileNewer(newFile, zonedDateTime), "New File - Newer - ZonedDateTime");
1743         assertTrue(FileUtils.isFileNewer(newFile, offsetDateTime), "New File - Newer - OffsetDateTime");
1744         assertTrue(FileUtils.isFileNewer(newFile, localDateTime), "New File - Newer - LocalDateTime");
1745         assertTrue(FileUtils.isFileNewer(newFile, localDateTime, ZoneId.systemDefault()), "New File - Newer - LocalDateTime,ZoneId");
1746         assertFalse(FileUtils.isFileNewer(newFile, localDate), "New File - Newer - LocalDate");
1747         assertTrue(FileUtils.isFileNewer(newFile, localDate, localTime0), "New File - Newer - LocalDate,LocalTime");
1748         assertTrue(FileUtils.isFileNewer(newFile, localDate, offsetTime0), "New File - Newer - LocalDate,OffsetTime");
1749         assertFalse(FileUtils.isFileNewer(newFile, localDatePlusDay), "New File - Newer - LocalDate plus one day");
1750         assertFalse(FileUtils.isFileNewer(newFile, localDatePlusDay, localTime0), "New File - Newer - LocalDate plus one day,LocalTime");
1751         assertFalse(FileUtils.isFileNewer(newFile, localDatePlusDay, offsetTime0), "New File - Newer - LocalDate plus one day,OffsetTime");
1752         assertFalse(FileUtils.isFileNewer(invalidFile, refFile), "Illegal - Newer - File");
1753         assertThrows(IllegalArgumentException.class, () -> FileUtils.isFileNewer(newFile, invalidFile));
1754 
1755         // Test isFileOlder()
1756         assertTrue(FileUtils.isFileOlder(oldFile, refFile), "Old File - Older - File");
1757         assertTrue(FileUtils.isFileOlder(oldFile, date), "Old File - Older - Date");
1758         assertTrue(FileUtils.isFileOlder(oldFile, now), "Old File - Older - Mili");
1759         assertTrue(FileUtils.isFileOlder(oldFile, instant), "Old File - Older - Instant");
1760         assertTrue(FileUtils.isFileOlder(oldFile, zonedDateTime), "Old File - Older - ZonedDateTime");
1761         assertTrue(FileUtils.isFileOlder(oldFile, offsetDateTime), "Old File - Older - OffsetDateTime");
1762         assertTrue(FileUtils.isFileOlder(oldFile, localDateTime), "Old File - Older - LocalDateTime");
1763         assertTrue(FileUtils.isFileOlder(oldFile, localDateTime, ZoneId.systemDefault()), "Old File - Older - LocalDateTime,LocalTime");
1764         assertTrue(FileUtils.isFileOlder(oldFile, localDate), "Old File - Older - LocalDate");
1765         assertFalse(FileUtils.isFileOlder(oldFile, localDate, localTime0), "Old File - Older - LocalDate,LocalTime");
1766         assertFalse(FileUtils.isFileOlder(oldFile, localDate, offsetTime0), "Old File - Older - LocalDate,OffsetTime");
1767         assertTrue(FileUtils.isFileOlder(oldFile, localDatePlusDay), "Old File - Older - LocalDate plus one day");
1768         assertTrue(FileUtils.isFileOlder(oldFile, localDatePlusDay, localTime0), "Old File - Older - LocalDate plus one day,LocalTime");
1769         assertTrue(FileUtils.isFileOlder(oldFile, localDatePlusDay, offsetTime0), "Old File - Older - LocalDate plus one day,OffsetTime");
1770 
1771         assertFalse(FileUtils.isFileOlder(newFile, refFile), "New File - Older - File");
1772         assertFalse(FileUtils.isFileOlder(newFile, date), "New File - Older - Date");
1773         assertFalse(FileUtils.isFileOlder(newFile, now), "New File - Older - Mili");
1774         assertFalse(FileUtils.isFileOlder(newFile, instant), "New File - Older - Instant");
1775         assertFalse(FileUtils.isFileOlder(newFile, zonedDateTime), "New File - Older - ZonedDateTime");
1776         assertFalse(FileUtils.isFileOlder(newFile, offsetDateTime), "New File - Older - OffsetDateTime");
1777         assertFalse(FileUtils.isFileOlder(newFile, localDateTime), "New File - Older - LocalDateTime");
1778         assertFalse(FileUtils.isFileOlder(newFile, localDateTime, ZoneId.systemDefault()), "New File - Older - LocalDateTime,ZoneId");
1779         assertTrue(FileUtils.isFileOlder(newFile, localDate), "New File - Older - LocalDate");
1780         assertFalse(FileUtils.isFileOlder(newFile, localDate, localTime0), "New File - Older - LocalDate,LocalTime");
1781         assertFalse(FileUtils.isFileOlder(newFile, localDate, offsetTime0), "New File - Older - LocalDate,OffsetTime");
1782         assertTrue(FileUtils.isFileOlder(newFile, localDatePlusDay), "New File - Older - LocalDate plus one day");
1783         assertTrue(FileUtils.isFileOlder(newFile, localDatePlusDay, localTime0), "New File - Older - LocalDate plus one day,LocalTime");
1784         assertTrue(FileUtils.isFileOlder(newFile, localDatePlusDay, offsetTime0), "New File - Older - LocalDate plus one day,OffsetTime");
1785 
1786         assertFalse(FileUtils.isFileOlder(invalidFile, refFile), "Illegal - Older - File");
1787         assertThrows(IllegalArgumentException.class, () -> FileUtils.isFileOlder(newFile, invalidFile));
1788 
1789         // Null File
1790         assertThrows(NullPointerException.class, () -> FileUtils.isFileNewer(null, now));
1791 
1792         // Null reference File
1793         assertThrows(NullPointerException.class, () -> FileUtils.isFileNewer(oldFile, (File) null));
1794 
1795         // Invalid reference File
1796         assertThrows(IllegalArgumentException.class, () -> FileUtils.isFileNewer(oldFile, invalidFile));
1797 
1798         // Null reference Date
1799         assertThrows(NullPointerException.class, () -> FileUtils.isFileNewer(oldFile, (Date) null));
1800 
1801         // ----- Test isFileOlder() exceptions -----
1802         // Null File
1803         assertThrows(NullPointerException.class, () -> FileUtils.isFileOlder(null, now));
1804 
1805         // Null reference File
1806         assertThrows(NullPointerException.class, () -> FileUtils.isFileOlder(oldFile, (File) null));
1807 
1808         // Null reference Date
1809         assertThrows(NullPointerException.class, () -> FileUtils.isFileOlder(oldFile, (Date) null));
1810 
1811         // Invalid reference File
1812         assertThrows(IllegalArgumentException.class, () -> FileUtils.isFileOlder(oldFile, invalidFile));
1813     }
1814 
1815     @Test
1816     public void testIsRegularFile() throws IOException {
1817         assertFalse(FileUtils.isRegularFile(null));
1818 
1819         assertFalse(FileUtils.isRegularFile(tempDirFile));
1820         assertTrue(FileUtils.isRegularFile(testFile1));
1821 
1822         Files.delete(testFile1.toPath());
1823         assertFalse(FileUtils.isRegularFile(testFile1));
1824     }
1825 
1826     @Test
1827     public void testIterateFiles() throws Exception {
1828         final File srcDir = tempDirFile;
1829         final File subDir = new File(srcDir, "list_test");
1830         final File subSubDir = new File(subDir, "subSubDir");
1831         final File notSubSubDir = new File(subDir, "notSubSubDir");
1832         assertTrue(subDir.mkdir());
1833         assertTrue(subSubDir.mkdir());
1834         assertTrue(notSubSubDir.mkdir());
1835         Iterator<File> iterator = null;
1836         try {
1837             // Need list to be appendable
1838             final List<String> expectedFileNames = new ArrayList<>(
1839                 Arrays.asList("a.txt", "b.txt", "c.txt", "d.txt", "e.txt", "f.txt"));
1840             final int[] fileSizes = {123, 234, 345, 456, 678, 789};
1841             assertEquals(expectedFileNames.size(), fileSizes.length);
1842             Collections.sort(expectedFileNames);
1843             Arrays.sort(fileSizes);
1844             for (int i = 0; i < fileSizes.length; ++i) {
1845                 TestUtils.generateTestData(new File(subDir, expectedFileNames.get(i)), fileSizes[i]);
1846             }
1847             //
1848             final String subSubFileName = "z.txt";
1849             TestUtils.generateTestData(new File(subSubDir, subSubFileName), 1);
1850             expectedFileNames.add(subSubFileName);
1851             //
1852             final String notSubSubFileName = "not.txt";
1853             TestUtils.generateTestData(new File(notSubSubDir, notSubSubFileName), 1);
1854 
1855             final WildcardFileFilter allFilesFileFilter = WildcardFileFilter.builder().setWildcards("*.*").get();
1856             final NameFileFilter dirFilter = new NameFileFilter("subSubDir");
1857             iterator = FileUtils.iterateFiles(subDir, allFilesFileFilter, dirFilter);
1858 
1859             final Map<String, String> matchedFileNames = new HashMap<>();
1860             final List<String> actualFileNames = new ArrayList<>();
1861 
1862             while (iterator.hasNext()) {
1863                 boolean found = false;
1864                 final String fileName = iterator.next().getName();
1865                 actualFileNames.add(fileName);
1866 
1867                 for (int j = 0; !found && j < expectedFileNames.size(); ++j) {
1868                     final String expectedFileName = expectedFileNames.get(j);
1869                     if (expectedFileName.equals(fileName)) {
1870                         matchedFileNames.put(expectedFileName, expectedFileName);
1871                         found = true;
1872                     }
1873                 }
1874             }
1875             assertEquals(expectedFileNames.size(), matchedFileNames.size());
1876             Collections.sort(actualFileNames);
1877             assertEquals(expectedFileNames, actualFileNames);
1878         } finally {
1879             consumeRemaining(iterator);
1880             notSubSubDir.delete();
1881             subSubDir.delete();
1882             subDir.delete();
1883         }
1884     }
1885 
1886     @Test
1887     public void testIterateFilesAndDirs() throws IOException {
1888         final File srcDir = tempDirFile;
1889         // temporaryFolder/srcDir
1890         // - subdir1
1891         // -- subdir2
1892         // --- a.txt
1893         // --- subdir3
1894         // --- subdir4
1895         final File subDir1 = new File(srcDir, "subdir1");
1896         final File subDir2 = new File(subDir1, "subdir2");
1897         final File subDir3 = new File(subDir2, "subdir3");
1898         final File subDir4 = new File(subDir2, "subdir4");
1899         assertTrue(subDir1.mkdir());
1900         assertTrue(subDir2.mkdir());
1901         assertTrue(subDir3.mkdir());
1902         assertTrue(subDir4.mkdir());
1903         final File someFile = new File(subDir2, "a.txt");
1904         final WildcardFileFilter fileFilterAllFiles =  WildcardFileFilter.builder().setWildcards("*.*").get();
1905         final WildcardFileFilter fileFilterAllDirs = WildcardFileFilter.builder().setWildcards("*").get();
1906         final WildcardFileFilter fileFilterExtTxt = WildcardFileFilter.builder().setWildcards("*.txt").get();
1907         try {
1908             try (OutputStream output = new BufferedOutputStream(Files.newOutputStream(someFile.toPath()))) {
1909                 TestUtils.generateTestData(output, 100);
1910             }
1911             //
1912             // "*.*" and "*"
1913             Collection<File> expectedFilesAndDirs = Arrays.asList(subDir1, subDir2, someFile, subDir3, subDir4);
1914             iterateFilesAndDirs(subDir1, fileFilterAllFiles, fileFilterAllDirs, expectedFilesAndDirs);
1915             //
1916             // "*.txt" and "*"
1917             final int filesCount;
1918             expectedFilesAndDirs = Arrays.asList(subDir1, subDir2, someFile, subDir3, subDir4);
1919             iterateFilesAndDirs(subDir1, fileFilterExtTxt, fileFilterAllDirs, expectedFilesAndDirs);
1920             //
1921             // "*.*" and "subdir2"
1922             expectedFilesAndDirs = Arrays.asList(subDir1, subDir2, someFile);
1923             iterateFilesAndDirs(subDir1, fileFilterAllFiles, new NameFileFilter("subdir2"), expectedFilesAndDirs);
1924             //
1925             // "*.txt" and "subdir2"
1926             expectedFilesAndDirs = Arrays.asList(subDir1, subDir2, someFile);
1927             iterateFilesAndDirs(subDir1, fileFilterExtTxt, new NameFileFilter("subdir2"), expectedFilesAndDirs);
1928         } finally {
1929             someFile.delete();
1930             subDir4.delete();
1931             subDir3.delete();
1932             subDir2.delete();
1933             subDir1.delete();
1934         }
1935     }
1936 
1937     @Test
1938     public void testIterateFilesOnlyNoDirs() throws IOException {
1939         final File directory = tempDirFile;
1940         assertTrue(new File(directory, "TEST").mkdir());
1941         assertTrue(new File(directory, "test.txt").createNewFile());
1942 
1943         final IOFileFilter filter = WildcardFileFilter.builder().setWildcards("*").setIoCase(IOCase.INSENSITIVE).get();
1944         FileUtils.iterateFiles(directory, filter, null).forEachRemaining(file -> assertFalse(file.isDirectory(), file::getAbsolutePath));
1945     }
1946 
1947     @Test
1948     public void testListFiles() throws Exception {
1949         final File srcDir = tempDirFile;
1950         final File subDir = new File(srcDir, "list_test");
1951         final File subDir2 = new File(subDir, "subdir");
1952         subDir.mkdir();
1953         subDir2.mkdir();
1954         try {
1955 
1956             final String[] expectedFileNames = { "a.txt", "b.txt", "c.txt", "d.txt", "e.txt", "f.txt" };
1957             final int[] fileSizes = { 123, 234, 345, 456, 678, 789 };
1958 
1959             for (int i = 0; i < expectedFileNames.length; ++i) {
1960                 final File theFile = new File(subDir, expectedFileNames[i]);
1961                 if (!theFile.getParentFile().exists()) {
1962                     fail("Cannot create file " + theFile + " as the parent directory does not exist");
1963                 }
1964                 try (final BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(theFile.toPath()))) {
1965                     TestUtils.generateTestData(output, fileSizes[i]);
1966                 }
1967             }
1968 
1969             // @formatter:off
1970             final Collection<File> actualFiles = FileUtils.listFiles(subDir,
1971                     WildcardFileFilter.builder().setWildcards("*.*").get(),
1972                     WildcardFileFilter.builder().setWildcards("*").get());
1973             // @formatter:on
1974 
1975             final int count = actualFiles.size();
1976             final Object[] fileObjs = actualFiles.toArray();
1977 
1978             assertEquals(expectedFileNames.length, actualFiles.size(), actualFiles::toString);
1979 
1980             final Map<String, String> foundFileNames = new HashMap<>();
1981 
1982             for (int i = 0; i < count; ++i) {
1983                 boolean found = false;
1984                 for (int j = 0; !found && j < expectedFileNames.length; ++j) {
1985                     if (expectedFileNames[j].equals(((File) fileObjs[i]).getName())) {
1986                         foundFileNames.put(expectedFileNames[j], expectedFileNames[j]);
1987                         found = true;
1988                     }
1989                 }
1990             }
1991 
1992             assertEquals(foundFileNames.size(), expectedFileNames.length, foundFileNames::toString);
1993         } finally {
1994             subDir.delete();
1995         }
1996     }
1997 
1998     @Test
1999     public void testListFilesOnlyNoDirs() throws IOException {
2000         final File directory = tempDirFile;
2001         assertTrue(new File(directory, "TEST").mkdir());
2002         assertTrue(new File(directory, "test.txt").createNewFile());
2003 
2004         final IOFileFilter filter = WildcardFileFilter.builder().setWildcards("*").setIoCase(IOCase.INSENSITIVE).get();
2005         for (final File file : FileUtils.listFiles(directory, filter, null)) {
2006             assertFalse(file.isDirectory(), file::getAbsolutePath);
2007         }
2008     }
2009 
2010     @Test
2011     public void testListFilesWithDirs() throws IOException {
2012         final File srcDir = tempDirFile;
2013 
2014         final File subDir1 = new File(srcDir, "subdir");
2015         final File subDir2 = new File(subDir1, "subdir2");
2016         subDir1.mkdir();
2017         subDir2.mkdir();
2018         try {
2019             final File someFile = new File(subDir2, "a.txt");
2020             if (!someFile.getParentFile().exists()) {
2021                 fail("Cannot create file " + someFile + " as the parent directory does not exist");
2022             }
2023             try (final BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(someFile.toPath()))) {
2024                 TestUtils.generateTestData(output, 100);
2025             }
2026 
2027             final File subDir3 = new File(subDir2, "subdir3");
2028             subDir3.mkdir();
2029 
2030             // @formatter:off
2031             final Collection<File> files = FileUtils.listFilesAndDirs(subDir1,
2032                     WildcardFileFilter.builder().setWildcards("*.*").get(),
2033                     WildcardFileFilter.builder().setWildcards("*").get());
2034             // @formatter:on
2035 
2036             assertEquals(4, files.size());
2037             assertTrue(files.contains(subDir1), "Should contain the directory.");
2038             assertTrue(files.contains(subDir2), "Should contain the directory.");
2039             assertTrue(files.contains(someFile), "Should contain the file.");
2040             assertTrue(files.contains(subDir3), "Should contain the directory.");
2041         } finally {
2042             subDir1.delete();
2043         }
2044     }
2045 
2046     @Test
2047     public void testMoveDirectory_CopyDelete() throws Exception {
2048 
2049         final File dir = tempDirFile;
2050         final File src = new File(dir, "testMoveDirectory2Source") {
2051             private static final long serialVersionUID = 1L;
2052 
2053             // Force renameTo to fail
2054             @Override
2055             public boolean renameTo(final File dest) {
2056                 return false;
2057             }
2058         };
2059         final File testDir = new File(src, "foo");
2060         final File testFile = new File(testDir, "bar");
2061         testDir.mkdirs();
2062         if (!testFile.getParentFile().exists()) {
2063             fail("Cannot create file " + testFile
2064                     + " as the parent directory does not exist");
2065         }
2066         try (final OutputStream output = new BufferedOutputStream(Files.newOutputStream(testFile.toPath()))) {
2067             TestUtils.generateTestData(output, 0);
2068         }
2069         final File destination = new File(dir, "testMoveDirectory1Dest");
2070         FileUtils.deleteDirectory(destination);
2071 
2072         // Move the directory
2073         FileUtils.moveDirectory(src, destination);
2074 
2075         // Check results
2076         assertTrue(destination.exists(), "Check Exist");
2077         assertFalse(src.exists(), "Original deleted");
2078         final File movedDir = new File(destination, testDir.getName());
2079         final File movedFile = new File(movedDir, testFile.getName());
2080         assertTrue(movedDir.exists(), "Check dir moved");
2081         assertTrue(movedFile.exists(), "Check file moved");
2082     }
2083 
2084     @Test
2085     public void testMoveDirectory_Errors() throws Exception {
2086         assertThrows(NullPointerException.class, () -> FileUtils.moveDirectory(null, new File("foo")));
2087         assertThrows(NullPointerException.class, () -> FileUtils.moveDirectory(new File("foo"), null));
2088         assertThrows(FileNotFoundException.class, () -> FileUtils.moveDirectory(new File("non-existent"), new File("foo")));
2089 
2090         final File testFile = new File(tempDirFile, "testMoveDirectoryFile");
2091         if (!testFile.getParentFile().exists()) {
2092             fail("Cannot create file " + testFile + " as the parent directory does not exist");
2093         }
2094         try (final OutputStream output = new BufferedOutputStream(Files.newOutputStream(testFile.toPath()))) {
2095             TestUtils.generateTestData(output, 0);
2096         }
2097         assertThrows(IllegalArgumentException.class, () -> FileUtils.moveDirectory(testFile, new File("foo")));
2098         final File testSrcFile = new File(tempDirFile, "testMoveDirectorySource");
2099         final File testDestFile = new File(tempDirFile, "testMoveDirectoryDest");
2100         testSrcFile.mkdir();
2101         testDestFile.mkdir();
2102         assertThrows(FileExistsException.class, () -> FileUtils.moveDirectory(testSrcFile, testDestFile),
2103             "Expected FileExistsException when dest already exists");
2104 
2105     }
2106 
2107     @Test
2108     public void testMoveDirectory_Rename() throws Exception {
2109         final File dir = tempDirFile;
2110         final File src = new File(dir, "testMoveDirectory1Source");
2111         final File testDir = new File(src, "foo");
2112         final File testFile = new File(testDir, "bar");
2113         testDir.mkdirs();
2114         if (!testFile.getParentFile().exists()) {
2115             fail("Cannot create file " + testFile
2116                     + " as the parent directory does not exist");
2117         }
2118         try (final OutputStream output = new BufferedOutputStream(Files.newOutputStream(testFile.toPath()))) {
2119             TestUtils.generateTestData(output, 0);
2120         }
2121         final File destination = new File(dir, "testMoveDirectory1Dest");
2122         FileUtils.deleteDirectory(destination);
2123 
2124         // Move the directory
2125         FileUtils.moveDirectory(src, destination);
2126 
2127         // Check results
2128         assertTrue(destination.exists(), "Check Exist");
2129         assertFalse(src.exists(), "Original deleted");
2130         final File movedDir = new File(destination, testDir.getName());
2131         final File movedFile = new File(movedDir, testFile.getName());
2132         assertTrue(movedDir.exists(), "Check dir moved");
2133         assertTrue(movedFile.exists(), "Check file moved");
2134     }
2135 
2136     @Test
2137     public void testMoveDirectoryToDirectory() throws Exception {
2138         final File dir = tempDirFile;
2139         final File src = new File(dir, "testMoveDirectory1Source");
2140         final File testChildDir = new File(src, "foo");
2141         final File testFile = new File(testChildDir, "bar");
2142         testChildDir.mkdirs();
2143         if (!testFile.getParentFile().exists()) {
2144             fail("Cannot create file " + testFile
2145                     + " as the parent directory does not exist");
2146         }
2147         try (final OutputStream output = new BufferedOutputStream(Files.newOutputStream(testFile.toPath()))) {
2148             TestUtils.generateTestData(output, 0);
2149         }
2150         final File destDir = new File(dir, "testMoveDirectory1Dest");
2151         FileUtils.deleteDirectory(destDir);
2152         assertFalse(destDir.exists(), "Check Exist before");
2153 
2154         // Move the directory
2155         FileUtils.moveDirectoryToDirectory(src, destDir, true);
2156 
2157         // Check results
2158         assertTrue(destDir.exists(), "Check Exist after");
2159         assertFalse(src.exists(), "Original deleted");
2160         final File movedDir = new File(destDir, src.getName());
2161         final File movedChildDir = new File(movedDir, testChildDir.getName());
2162         final File movedFile = new File(movedChildDir, testFile.getName());
2163         assertTrue(movedDir.exists(), "Check dir moved");
2164         assertTrue(movedChildDir.exists(), "Check child dir moved");
2165         assertTrue(movedFile.exists(), "Check file moved");
2166     }
2167 
2168     @Test
2169     public void testMoveDirectoryToDirectory_Errors() throws Exception {
2170         assertThrows(NullPointerException.class, () -> FileUtils.moveDirectoryToDirectory(null, new File("foo"), true));
2171         assertThrows(NullPointerException.class, () -> FileUtils.moveDirectoryToDirectory(new File("foo"), null, true));
2172         final File testFile1 = new File(tempDirFile, "testMoveFileFile1");
2173         final File testFile2 = new File(tempDirFile, "testMoveFileFile2");
2174         if (!testFile1.getParentFile().exists()) {
2175             fail("Cannot create file " + testFile1 + " as the parent directory does not exist");
2176         }
2177         try (final BufferedOutputStream output1 = new BufferedOutputStream(Files.newOutputStream(testFile1.toPath()))) {
2178             TestUtils.generateTestData(output1, 0);
2179         }
2180         if (!testFile2.getParentFile().exists()) {
2181             fail("Cannot create file " + testFile2 + " as the parent directory does not exist");
2182         }
2183         try (final BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(testFile2.toPath()))) {
2184             TestUtils.generateTestData(output, 0);
2185         }
2186         assertThrows(IOException.class, () -> FileUtils.moveDirectoryToDirectory(testFile1, testFile2, true));
2187 
2188         final File nonExistent = new File(tempDirFile, "testMoveFileNonExistent");
2189         assertThrows(IOException.class, () -> FileUtils.moveDirectoryToDirectory(testFile1, nonExistent, false));
2190     }
2191 
2192     @Test
2193     public void testMoveFile_CopyDelete() throws Exception {
2194         final File destination = new File(tempDirFile, "move2.txt");
2195         final File src = new File(testFile1.getAbsolutePath()) {
2196             private static final long serialVersionUID = 1L;
2197 
2198             // Force renameTo to fail, as if destination is on another
2199             // filesystem
2200             @Override
2201             public boolean renameTo(final File f) {
2202                 return false;
2203             }
2204         };
2205         FileUtils.moveFile(src, destination);
2206         assertTrue(destination.exists(), "Check Exist");
2207         assertFalse(src.exists(), "Original deleted");
2208     }
2209 
2210     @Test
2211     public void testMoveFile_CopyDelete_Failed() {
2212         final File destination = new File(tempDirFile, "move3.txt");
2213         final File src = new File(testFile1.getAbsolutePath()) {
2214             private static final long serialVersionUID = 1L;
2215 
2216             // Force delete failure
2217             @Override
2218             public boolean delete() {
2219                 return false;
2220             }
2221 
2222             // Force renameTo to fail, as if destination is on another
2223             // filesystem
2224             @Override
2225             public boolean renameTo(final File f) {
2226                 return false;
2227             }
2228 
2229         };
2230         assertThrows(IOException.class, () -> FileUtils.moveFile(src, destination));
2231         // expected
2232         assertFalse(destination.exists(), "Check Rollback");
2233         assertTrue(src.exists(), "Original exists");
2234     }
2235 
2236     @Test
2237     public void testMoveFile_CopyDelete_WithFileDatePreservation() throws Exception {
2238         final File destination = new File(tempDirFile, "move2.txt");
2239 
2240         backDateFile10Minutes(testFile1); // set test file back 10 minutes
2241 
2242         final File src = new File(testFile1.getAbsolutePath()) {
2243             private static final long serialVersionUID = 1L;
2244 
2245             // Force renameTo to fail, as if destination is on another
2246             // filesystem
2247             @Override
2248             public boolean renameTo(final File f) {
2249                 return false;
2250             }
2251         };
2252         final long expected = getLastModifiedMillis(testFile1);
2253 
2254         FileUtils.moveFile(src, destination, StandardCopyOption.COPY_ATTRIBUTES);
2255         assertTrue(destination.exists(), "Check Exist");
2256         assertFalse(src.exists(), "Original deleted");
2257 
2258         final long destLastMod = getLastModifiedMillis(destination);
2259         final long delta = destLastMod - expected;
2260         assertEquals(expected, destLastMod, "Check last modified date same as input, delta " + delta);
2261     }
2262 
2263     @Test
2264     public void testMoveFile_CopyDelete_WithoutFileDatePreservation() throws Exception {
2265         final File destination = new File(tempDirFile, "move2.txt");
2266 
2267         backDateFile10Minutes(testFile1); // set test file back 10 minutes
2268 
2269         // destination file time should not be less than this (allowing for granularity)
2270         final long nowMillis = System.currentTimeMillis() - 1000L;
2271 
2272         final File src = new File(testFile1.getAbsolutePath()) {
2273             private static final long serialVersionUID = 1L;
2274 
2275             // Force renameTo to fail, as if destination is on another
2276             // filesystem
2277             @Override
2278             public boolean renameTo(final File f) {
2279                 return false;
2280             }
2281         };
2282         final long unexpectedMillis = getLastModifiedMillis(testFile1);
2283 
2284         FileUtils.moveFile(src, destination, PathUtils.EMPTY_COPY_OPTIONS);
2285         assertTrue(destination.exists(), "Check Exist");
2286         assertFalse(src.exists(), "Original deleted");
2287 
2288         // On Windows, the last modified time is copied by default.
2289         if (!SystemUtils.IS_OS_WINDOWS) {
2290             final long destLastModMillis = getLastModifiedMillis(destination);
2291             final long deltaMillis = destLastModMillis - unexpectedMillis;
2292             assertNotEquals(unexpectedMillis, destLastModMillis,
2293                 "Check last modified date not same as input, delta " + deltaMillis);
2294             assertTrue(destLastModMillis > nowMillis,
2295                 destLastModMillis + " > " + nowMillis + " (delta " + deltaMillis + ")");
2296         }
2297     }
2298 
2299     @Test
2300     public void testMoveFile_Errors() throws Exception {
2301         assertThrows(NullPointerException.class, () -> FileUtils.moveFile(null, new File("foo")));
2302         assertThrows(NullPointerException.class, () -> FileUtils.moveFile(new File("foo"), null));
2303         assertThrows(FileNotFoundException.class, () -> FileUtils.moveFile(new File("non-existent"), new File("foo")));
2304         assertThrows(IllegalArgumentException.class, () -> FileUtils.moveFile(tempDirFile, new File("foo")));
2305         final File testSourceFile = new File(tempDirFile, "testMoveFileSource");
2306         final File testDestFile = new File(tempDirFile, "testMoveFileSource");
2307         if (!testSourceFile.getParentFile().exists()) {
2308             fail("Cannot create file " + testSourceFile + " as the parent directory does not exist");
2309         }
2310         final BufferedOutputStream output1 = new BufferedOutputStream(Files.newOutputStream(testSourceFile.toPath()));
2311         try {
2312             TestUtils.generateTestData(output1, 0);
2313         } finally {
2314             IOUtils.closeQuietly(output1);
2315         }
2316         assertTrue(testDestFile.getParentFile().exists(), () -> "Cannot create file " + testDestFile + " as the parent directory does not exist");
2317         final BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(testDestFile.toPath()));
2318         try {
2319             TestUtils.generateTestData(output, 0);
2320         } finally {
2321             IOUtils.closeQuietly(output);
2322         }
2323         assertThrows(FileExistsException.class, () -> FileUtils.moveFile(testSourceFile, testDestFile),
2324             "Expected FileExistsException when dest already exists");
2325     }
2326 
2327     @Test
2328     public void testMoveFile_Rename() throws Exception {
2329         final File destination = new File(tempDirFile, "move1.txt");
2330 
2331         FileUtils.moveFile(testFile1, destination);
2332         assertTrue(destination.exists(), "Check Exist");
2333         assertFalse(testFile1.exists(), "Original deleted");
2334     }
2335 
2336     @Test
2337     public void testMoveFileToDirectory() throws Exception {
2338         final File destDir = new File(tempDirFile, "moveFileDestDir");
2339         final File movedFile = new File(destDir, testFile1.getName());
2340         assertFalse(destDir.exists(), "Check Exist before");
2341         assertFalse(movedFile.exists(), "Check Exist before");
2342 
2343         FileUtils.moveFileToDirectory(testFile1, destDir, true);
2344         assertTrue(movedFile.exists(), "Check Exist after");
2345         assertFalse(testFile1.exists(), "Original deleted");
2346     }
2347 
2348     @Test
2349     public void testMoveFileToDirectory_Errors() throws Exception {
2350         assertThrows(NullPointerException.class, () -> FileUtils.moveFileToDirectory(null, new File("foo"), true));
2351         assertThrows(NullPointerException.class, () -> FileUtils.moveFileToDirectory(new File("foo"), null, true));
2352         final File testFile1 = new File(tempDirFile, "testMoveFileFile1");
2353         final File testFile2 = new File(tempDirFile, "testMoveFileFile2");
2354         if (!testFile1.getParentFile().exists()) {
2355             fail("Cannot create file " + testFile1 + " as the parent directory does not exist");
2356         }
2357         try (final BufferedOutputStream output1 = new BufferedOutputStream(Files.newOutputStream(testFile1.toPath()))) {
2358             TestUtils.generateTestData(output1, 0);
2359         }
2360         if (!testFile2.getParentFile().exists()) {
2361             fail("Cannot create file " + testFile2 + " as the parent directory does not exist");
2362         }
2363         final BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(testFile2.toPath()));
2364         try {
2365             TestUtils.generateTestData(output, 0);
2366         } finally {
2367             IOUtils.closeQuietly(output);
2368         }
2369         assertThrows(IllegalArgumentException.class, () -> FileUtils.moveFileToDirectory(testFile1, testFile2, true));
2370 
2371         final File nonExistent = new File(tempDirFile, "testMoveFileNonExistent");
2372         assertThrows(IOException.class, () -> FileUtils.moveFileToDirectory(testFile1, nonExistent, false));
2373     }
2374 
2375     @Test
2376     public void testMoveToDirectory() throws Exception {
2377         final File destDir = new File(tempDirFile, "testMoveToDirectoryDestDir");
2378         final File testDir = new File(tempDirFile, "testMoveToDirectoryTestDir");
2379         final File testFile = new File(tempDirFile, "testMoveToDirectoryTestFile");
2380         testDir.mkdirs();
2381         if (!testFile.getParentFile().exists()) {
2382             fail("Cannot create file " + testFile
2383                     + " as the parent directory does not exist");
2384         }
2385         final BufferedOutputStream output =
2386                 new BufferedOutputStream(Files.newOutputStream(testFile.toPath()));
2387         try {
2388             TestUtils.generateTestData(output, 0);
2389         } finally {
2390             IOUtils.closeQuietly(output);
2391         }
2392         final File movedFile = new File(destDir, testFile.getName());
2393         final File movedDir = new File(destDir, testFile.getName());
2394 
2395         assertFalse(movedFile.exists(), "Check File Doesnt exist");
2396         assertFalse(movedDir.exists(), "Check Dir Doesnt exist");
2397 
2398         // Test moving a file
2399         FileUtils.moveToDirectory(testFile, destDir, true);
2400         assertTrue(movedFile.exists(), "Check File exists");
2401         assertFalse(testFile.exists(), "Check Original File doesn't exist");
2402 
2403         // Test moving a directory
2404         FileUtils.moveToDirectory(testDir, destDir, true);
2405         assertTrue(movedDir.exists(), "Check Dir exists");
2406         assertFalse(testDir.exists(), "Check Original Dir doesn't exist");
2407     }
2408 
2409     @Test
2410     public void testMoveToDirectory_Errors() throws Exception {
2411         assertThrows(NullPointerException.class, () -> FileUtils.moveDirectoryToDirectory(null, new File("foo"), true));
2412         assertThrows(NullPointerException.class, () -> FileUtils.moveDirectoryToDirectory(new File("foo"), null, true));
2413         final File nonExistent = new File(tempDirFile, "non-existent");
2414         final File destDir = new File(tempDirFile, "MoveToDirectoryDestDir");
2415         assertThrows(IOException.class, () -> FileUtils.moveToDirectory(nonExistent, destDir, true), "Expected IOException when source does not exist");
2416 
2417     }
2418 
2419     @Test
2420     public void testReadFileToByteArray() throws Exception {
2421         final File file = new File(tempDirFile, "read.txt");
2422         Files.write(file.toPath(), new byte[] {11, 21, 31});
2423 
2424         final byte[] data = FileUtils.readFileToByteArray(file);
2425         assertEquals(3, data.length);
2426         assertEquals(11, data[0]);
2427         assertEquals(21, data[1]);
2428         assertEquals(31, data[2]);
2429     }
2430 
2431     @Test
2432     public void testReadFileToByteArray_Errors() {
2433         assertThrows(NullPointerException.class, () -> FileUtils.readFileToByteArray(null));
2434         assertThrows(IOException.class, () -> FileUtils.readFileToByteArray(new File("non-exsistent")));
2435         assertThrows(IOException.class, () -> FileUtils.readFileToByteArray(tempDirFile));
2436     }
2437 
2438     @Test
2439     @EnabledIf("isPosixFilePermissionsSupported")
2440     public void testReadFileToByteArray_IOExceptionOnPosixFileSystem() throws Exception {
2441         final File file = TestUtils.newFile(tempDirFile, "cant-read.txt");
2442         TestUtils.createFile(file, 100);
2443         Files.setPosixFilePermissions(file.toPath(), PosixFilePermissions.fromString("---------"));
2444 
2445         assertThrows(IOException.class, () -> FileUtils.readFileToByteArray(file));
2446     }
2447 
2448     @Test
2449     public void testReadFileToString_Errors() {
2450         assertThrows(NullPointerException.class, () -> FileUtils.readFileToString(null));
2451         assertThrows(IOException.class, () -> FileUtils.readFileToString(new File("non-exsistent")));
2452         assertThrows(IOException.class, () -> FileUtils.readFileToString(tempDirFile));
2453         assertThrows(UnsupportedCharsetException.class, () -> FileUtils.readFileToString(tempDirFile, "unsupported-charset"));
2454     }
2455 
2456     @Test
2457     @EnabledIf("isPosixFilePermissionsSupported")
2458     public void testReadFileToString_IOExceptionOnPosixFileSystem() throws Exception {
2459         final File file = TestUtils.newFile(tempDirFile, "cant-read.txt");
2460         TestUtils.createFile(file, 100);
2461         Files.setPosixFilePermissions(file.toPath(), PosixFilePermissions.fromString("---------"));
2462 
2463         assertThrows(IOException.class, () -> FileUtils.readFileToString(file));
2464     }
2465 
2466     @Test
2467     public void testReadFileToStringWithDefaultEncoding() throws Exception {
2468         final File file = new File(tempDirFile, "read.obj");
2469         final String fixture = "Hello /u1234";
2470         Files.write(file.toPath(), fixture.getBytes());
2471 
2472         assertEquals(fixture, FileUtils.readFileToString(file));
2473     }
2474 
2475     @Test
2476     public void testReadFileToStringWithEncoding() throws Exception {
2477         final File file = new File(tempDirFile, "read.obj");
2478         final byte[] text = "Hello /u1234".getBytes(StandardCharsets.UTF_8);
2479         Files.write(file.toPath(), text);
2480 
2481         final String data = FileUtils.readFileToString(file, "UTF8");
2482         assertEquals("Hello /u1234", data);
2483     }
2484 
2485     @Test
2486     public void testReadLines() throws Exception {
2487         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
2488         try {
2489             final String[] data = {"hello", "/u1234", "", "this is", "some text"};
2490             TestUtils.createLineBasedFile(file, data);
2491 
2492             final List<String> lines = FileUtils.readLines(file, UTF_8);
2493             assertEquals(Arrays.asList(data), lines);
2494         } finally {
2495             TestUtils.deleteFile(file);
2496         }
2497     }
2498 
2499     @Test
2500     public void testReadLines_Errors() {
2501         assertThrows(NullPointerException.class, () -> FileUtils.readLines(null));
2502         assertThrows(IOException.class, () -> FileUtils.readLines(new File("non-exsistent")));
2503         assertThrows(IOException.class, () -> FileUtils.readLines(tempDirFile));
2504         assertThrows(UnsupportedCharsetException.class, () -> FileUtils.readLines(tempDirFile, "unsupported-charset"));
2505     }
2506 
2507     @Test
2508     @EnabledIf("isPosixFilePermissionsSupported")
2509     public void testReadLines_IOExceptionOnPosixFileSystem() throws Exception {
2510         final File file = TestUtils.newFile(tempDirFile, "cant-read.txt");
2511         TestUtils.createFile(file, 100);
2512         Files.setPosixFilePermissions(file.toPath(), PosixFilePermissions.fromString("---------"));
2513 
2514         assertThrows(IOException.class, () -> FileUtils.readLines(file));
2515     }
2516 
2517     @Test
2518     public void testSizeOf() throws Exception {
2519         final File file = new File(tempDirFile, getName());
2520 
2521         // Null argument
2522         assertThrows(NullPointerException.class, () -> FileUtils.sizeOf(null));
2523 
2524         // Non-existent file
2525         assertThrows(IllegalArgumentException.class, () -> FileUtils.sizeOf(file));
2526 
2527         // Creates file
2528         file.createNewFile();
2529 
2530         // New file
2531         assertEquals(0, FileUtils.sizeOf(file));
2532         file.delete();
2533 
2534         // Existing file
2535         assertEquals(testFile1Size, FileUtils.sizeOf(testFile1), "Unexpected files size");
2536 
2537         // Existing directory
2538         assertEquals(TEST_DIRECTORY_SIZE, FileUtils.sizeOf(tempDirFile), "Unexpected directory size");
2539     }
2540 
2541     @Test
2542     public void testSizeOfAsBigInteger() throws Exception {
2543         final File file = new File(tempDirFile, getName());
2544 
2545         // Null argument
2546         assertThrows(NullPointerException.class, () -> FileUtils.sizeOfAsBigInteger(null));
2547         // Non-existent file
2548         assertThrows(IllegalArgumentException.class, () -> FileUtils.sizeOfAsBigInteger(file));
2549 
2550         // Creates file
2551         file.createNewFile();
2552 
2553         // New file
2554         assertEquals(BigInteger.ZERO, FileUtils.sizeOfAsBigInteger(file));
2555         file.delete();
2556 
2557         // Existing file
2558         assertEquals(BigInteger.valueOf(testFile1Size), FileUtils.sizeOfAsBigInteger(testFile1),
2559                 "Unexpected files size");
2560 
2561         // Existing directory
2562         assertEquals(TEST_DIRECTORY_SIZE_BI, FileUtils.sizeOfAsBigInteger(tempDirFile),
2563                 "Unexpected directory size");
2564     }
2565 
2566     /**
2567      * Requires admin privileges on Windows.
2568      *
2569      * @throws Exception For example java.nio.file.FileSystemException:
2570      *                   C:\Users\you\AppData\Local\Temp\junit2324629522183300191\FileUtilsTest8613879743106252609\symlinked-dir: A required privilege is
2571      *                   not held by the client.
2572      */
2573     @Test
2574     public void testSizeOfDirectory() throws Exception {
2575         final File file = new File(tempDirFile, getName());
2576 
2577         // Null argument
2578         assertThrows(NullPointerException.class, () -> FileUtils.sizeOfDirectory(null));
2579         // Non-existent file
2580         assertThrows(IllegalArgumentException.class, () -> FileUtils.sizeOfAsBigInteger(file));
2581 
2582         // Creates file
2583         file.createNewFile();
2584 
2585         // Existing file
2586         assertThrows(IllegalArgumentException.class, () -> FileUtils.sizeOfDirectory(file));
2587 
2588         // Existing directory
2589         file.delete();
2590         file.mkdir();
2591 
2592         // Create a cyclic symlink
2593         this.createCircularSymLink(file);
2594 
2595         assertEquals(TEST_DIRECTORY_SIZE, FileUtils.sizeOfDirectory(file), "Unexpected directory size");
2596     }
2597 
2598     /**
2599      * Requires admin privileges on Windows.
2600      *
2601      * @throws Exception For example java.nio.file.FileSystemException:
2602      *                   C:\Users\you\AppData\Local\Temp\junit2324629522183300191\FileUtilsTest8613879743106252609\symlinked-dir: A required privilege is
2603      *                   not held by the client.
2604      */
2605     @Test
2606     public void testSizeOfDirectoryAsBigInteger() throws Exception {
2607         final File file = new File(tempDirFile, getName());
2608 
2609         // Null argument
2610         assertThrows(NullPointerException.class, () -> FileUtils.sizeOfDirectoryAsBigInteger(null));
2611         // Non-existent file
2612         assertThrows(IllegalArgumentException.class, () -> FileUtils.sizeOfDirectoryAsBigInteger(file));
2613 
2614         // Creates file
2615         file.createNewFile();
2616 
2617         // Existing file
2618         assertThrows(IllegalArgumentException.class, () -> FileUtils.sizeOfDirectoryAsBigInteger(file));
2619 
2620         // Existing directory
2621         file.delete();
2622         file.mkdir();
2623 
2624         createCircularSymLink(file);
2625 
2626         assertEquals(TEST_DIRECTORY_SIZE_BI, FileUtils.sizeOfDirectoryAsBigInteger(file), "Unexpected directory size");
2627 
2628         // Existing directory which size is greater than zero
2629         file.delete();
2630         file.mkdir();
2631 
2632         final File nonEmptyFile = new File(file, "non-emptyFile" + System.nanoTime());
2633         assertTrue(nonEmptyFile.getParentFile().exists(), () -> "Cannot create file " + nonEmptyFile + " as the parent directory does not exist");
2634         final OutputStream output = new BufferedOutputStream(Files.newOutputStream(nonEmptyFile.toPath()));
2635         try {
2636             TestUtils.generateTestData(output, TEST_DIRECTORY_SIZE_GT_ZERO_BI.longValue());
2637         } finally {
2638             IOUtils.closeQuietly(output);
2639         }
2640 
2641         assertEquals(TEST_DIRECTORY_SIZE_GT_ZERO_BI, FileUtils.sizeOfDirectoryAsBigInteger(file), "Unexpected directory size");
2642 
2643         nonEmptyFile.delete();
2644         file.delete();
2645     }
2646 
2647     @Test
2648     public void testToFile1() throws Exception {
2649         final URL url = new URL("file", null, "a/b/c/file.txt");
2650         final File file = FileUtils.toFile(url);
2651         assertTrue(file.toString().contains("file.txt"));
2652     }
2653 
2654     @Test
2655     public void testToFile2() throws Exception {
2656         final URL url = new URL("file", null, "a/b/c/file%20n%61me%2520.tx%74");
2657         final File file = FileUtils.toFile(url);
2658         assertTrue(file.toString().contains("file name%20.txt"));
2659     }
2660 
2661     @Test
2662     public void testToFile3() throws Exception {
2663         assertNull(FileUtils.toFile(null));
2664         assertNull(FileUtils.toFile(new URL("http://jakarta.apache.org")));
2665     }
2666 
2667     @Test
2668     public void testToFile4() throws Exception {
2669         final URL url = new URL("file", null, "a/b/c/file%%20%me.txt%");
2670         final File file = FileUtils.toFile(url);
2671         assertTrue(file.toString().contains("file% %me.txt%"));
2672     }
2673 
2674     /* IO-252 */
2675     @Test
2676     public void testToFile5() throws Exception {
2677         final URL url = new URL("file", null, "both%20are%20100%20%25%20true");
2678         final File file = FileUtils.toFile(url);
2679         assertEquals("both are 100 % true", file.toString());
2680     }
2681 
2682     @Test
2683     public void testToFiles1() throws Exception {
2684         final URL[] urls = {
2685                 new URL("file", null, "file1.txt"),
2686                 new URL("file", null, "file2.txt"),
2687         };
2688         final File[] files = FileUtils.toFiles(urls);
2689 
2690         assertEquals(urls.length, files.length);
2691         assertTrue(files[0].toString().contains("file1.txt"), "File: " + files[0]);
2692         assertTrue(files[1].toString().contains("file2.txt"), "File: " + files[1]);
2693     }
2694 
2695     @Test
2696     public void testToFiles2() throws Exception {
2697         final URL[] urls = {
2698                 new URL("file", null, "file1.txt"),
2699                 null,
2700         };
2701         final File[] files = FileUtils.toFiles(urls);
2702 
2703         assertEquals(urls.length, files.length);
2704         assertTrue(files[0].toString().contains("file1.txt"), "File: " + files[0]);
2705         assertNull(files[1], "File: " + files[1]);
2706     }
2707 
2708     @Test
2709     public void testToFiles3() throws Exception {
2710         final URL[] urls = null;
2711         final File[] files = FileUtils.toFiles(urls);
2712 
2713         assertEquals(0, files.length);
2714     }
2715 
2716     @Test
2717     public void testToFiles3a() throws Exception {
2718         final URL[] urls = {}; // empty array
2719         final File[] files = FileUtils.toFiles(urls);
2720 
2721         assertEquals(0, files.length);
2722     }
2723 
2724     @Test
2725     public void testToFiles4() throws Exception {
2726         final URL[] urls = {
2727                 new URL("file", null, "file1.txt"),
2728                 new URL("http", "jakarta.apache.org", "file1.txt"),
2729         };
2730         assertThrows(IllegalArgumentException.class, () -> FileUtils.toFiles(urls));
2731     }
2732 
2733     @Test
2734     public void testToFileUtf8() throws Exception {
2735         final URL url = new URL("file", null, "/home/%C3%A4%C3%B6%C3%BC%C3%9F");
2736         final File file = FileUtils.toFile(url);
2737         assertTrue(file.toString().contains("\u00E4\u00F6\u00FC\u00DF"));
2738     }
2739 
2740     @Test
2741     public void testTouch() throws IOException {
2742         assertThrows(NullPointerException.class, () -> FileUtils.touch(null));
2743 
2744         final File file = new File(tempDirFile, "touch.txt");
2745         if (file.exists()) {
2746             file.delete();
2747         }
2748         assertFalse(file.exists(), "Bad test: test file still exists");
2749         FileUtils.touch(file);
2750         assertTrue(file.exists(), "FileUtils.touch() created file");
2751         try (OutputStream out = Files.newOutputStream(file.toPath())) {
2752             assertEquals(0, file.length(), "Created empty file.");
2753             out.write(0);
2754         }
2755         assertEquals(1, file.length(), "Wrote one byte to file");
2756         final long y2k = new GregorianCalendar(2000, 0, 1).getTime().getTime();
2757         final boolean res = setLastModifiedMillis(file, y2k);  // 0L fails on Win98
2758         assertTrue(res, "Bad test: set lastModified failed");
2759         assertEquals(y2k, getLastModifiedMillis(file), "Bad test: set lastModified set incorrect value");
2760         final long nowMillis = System.currentTimeMillis();
2761         FileUtils.touch(file);
2762         assertEquals(1, file.length(), "FileUtils.touch() didn't empty the file.");
2763         assertNotEquals(y2k, getLastModifiedMillis(file), "FileUtils.touch() changed lastModified");
2764         final int delta = 3000;
2765         assertTrue(getLastModifiedMillis(file) >= nowMillis - delta, "FileUtils.touch() changed lastModified to more than now-3s");
2766         assertTrue(getLastModifiedMillis(file) <= nowMillis + delta, "FileUtils.touch() changed lastModified to less than now+3s");
2767     }
2768 
2769     @Test
2770     public void testTouchDirDoesNotExist() throws Exception {
2771         final File file = new File("target/does-not-exist", "touchme.txt");
2772         final File parentDir = file.getParentFile();
2773         file.delete();
2774         parentDir.delete();
2775         assertFalse(parentDir.exists());
2776         assertFalse(file.exists());
2777         FileUtils.touch(file);
2778         assertTrue(parentDir.exists());
2779         assertTrue(file.exists());
2780     }
2781 
2782     @Test
2783     public void testToURLs1() throws Exception {
2784         final File[] files = {
2785                 new File(tempDirFile, "file1.txt"),
2786                 new File(tempDirFile, "file2.txt"),
2787                 new File(tempDirFile, "test file.txt"),
2788         };
2789         final URL[] urls = FileUtils.toURLs(files);
2790 
2791         assertEquals(files.length, urls.length);
2792         assertTrue(urls[0].toExternalForm().startsWith("file:"));
2793         assertTrue(urls[0].toExternalForm().contains("file1.txt"));
2794         assertTrue(urls[1].toExternalForm().startsWith("file:"));
2795         assertTrue(urls[1].toExternalForm().contains("file2.txt"));
2796 
2797         // Test escaped char
2798         assertTrue(urls[2].toExternalForm().startsWith("file:"));
2799         assertTrue(urls[2].toExternalForm().contains("test%20file.txt"));
2800     }
2801 
2802     @Test
2803     public void testToURLs3a() throws Exception {
2804         final File[] files = {}; // empty array
2805         final URL[] urls = FileUtils.toURLs(files);
2806 
2807         assertEquals(0, urls.length);
2808     }
2809 
2810     @Test
2811     public void testWrite_WithAppendOptionFalse_ShouldDeletePreviousFileLines() throws Exception {
2812         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
2813         FileUtils.writeStringToFile(file, "This line was there before you...");
2814 
2815         FileUtils.write(file, "this is brand new data", false);
2816 
2817         final String expected = "this is brand new data";
2818         final String actual = FileUtils.readFileToString(file);
2819         assertEquals(expected, actual);
2820     }
2821 
2822     @Test
2823     public void testWrite_WithAppendOptionTrue_ShouldNotDeletePreviousFileLines() throws Exception {
2824         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
2825         FileUtils.writeStringToFile(file, "This line was there before you...");
2826 
2827         FileUtils.write(file, "this is brand new data", true);
2828 
2829         final String expected = "This line was there before you..."
2830                 + "this is brand new data";
2831         final String actual = FileUtils.readFileToString(file);
2832         assertEquals(expected, actual);
2833     }
2834 
2835     @Test
2836     public void testWriteByteArrayToFile() throws Exception {
2837         final File file = new File(tempDirFile, "write.obj");
2838         final byte[] data = {11, 21, 31};
2839         FileUtils.writeByteArrayToFile(file, data);
2840         TestUtils.assertEqualContent(data, file);
2841     }
2842 
2843     @Test
2844     public void testWriteByteArrayToFile_WithAppendOptionFalse_ShouldDeletePreviousFileLines() throws Exception {
2845         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
2846         FileUtils.writeStringToFile(file, "This line was there before you...");
2847 
2848         FileUtils.writeByteArrayToFile(file, "this is brand new data".getBytes(), false);
2849 
2850         final String expected = "this is brand new data";
2851         final String actual = FileUtils.readFileToString(file);
2852         assertEquals(expected, actual);
2853     }
2854 
2855     @Test
2856     public void testWriteByteArrayToFile_WithAppendOptionTrue_ShouldNotDeletePreviousFileLines() throws Exception {
2857         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
2858         FileUtils.writeStringToFile(file, "This line was there before you...");
2859 
2860         FileUtils.writeByteArrayToFile(file, "this is brand new data".getBytes(), true);
2861 
2862         final String expected = "This line was there before you..."
2863                 + "this is brand new data";
2864         final String actual = FileUtils.readFileToString(file);
2865         assertEquals(expected, actual);
2866     }
2867 
2868     @Test
2869     public void testWriteByteArrayToFile_WithOffsetAndLength() throws Exception {
2870         final File file = new File(tempDirFile, "write.obj");
2871         final byte[] data = {11, 21, 32, 41, 51};
2872         final byte[] writtenData = new byte[3];
2873         System.arraycopy(data, 1, writtenData, 0, 3);
2874         FileUtils.writeByteArrayToFile(file, data, 1, 3);
2875         TestUtils.assertEqualContent(writtenData, file);
2876     }
2877 
2878     @Test
2879     public void testWriteByteArrayToFile_WithOffsetAndLength_WithAppendOptionTrue_ShouldDeletePreviousFileLines() throws Exception {
2880         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
2881         FileUtils.writeStringToFile(file, "This line was there before you...");
2882 
2883         final byte[] data = "SKIP_THIS_this is brand new data_AND_SKIP_THIS".getBytes(StandardCharsets.UTF_8);
2884         FileUtils.writeByteArrayToFile(file, data, 10, 22, false);
2885 
2886         final String expected = "this is brand new data";
2887         final String actual = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
2888         assertEquals(expected, actual);
2889     }
2890 
2891     @Test
2892     public void testWriteByteArrayToFile_WithOffsetAndLength_WithAppendOptionTrue_ShouldNotDeletePreviousFileLines() throws Exception {
2893         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
2894         FileUtils.writeStringToFile(file, "This line was there before you...");
2895 
2896         final byte[] data = "SKIP_THIS_this is brand new data_AND_SKIP_THIS".getBytes(StandardCharsets.UTF_8);
2897         FileUtils.writeByteArrayToFile(file, data, 10, 22, true);
2898 
2899         final String expected = "This line was there before you..." + "this is brand new data";
2900         final String actual = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
2901         assertEquals(expected, actual);
2902     }
2903 
2904     @Test
2905     public void testWriteCharSequence1() throws Exception {
2906         final File file = new File(tempDirFile, "write.txt");
2907         FileUtils.write(file, "Hello /u1234", "UTF8");
2908         final byte[] text = "Hello /u1234".getBytes(StandardCharsets.UTF_8);
2909         TestUtils.assertEqualContent(text, file);
2910     }
2911 
2912     @Test
2913     public void testWriteCharSequence2() throws Exception {
2914         final File file = new File(tempDirFile, "write.txt");
2915         FileUtils.write(file, "Hello /u1234", (String) null);
2916         final byte[] text = "Hello /u1234".getBytes();
2917         TestUtils.assertEqualContent(text, file);
2918     }
2919 
2920 
2921     @Test
2922     public void testWriteLines_3arg_nullSeparator() throws Exception {
2923         final Object[] data = {
2924                 "hello", new StringBuffer("world"), "", "this is", null, "some text"};
2925         final List<Object> list = Arrays.asList(data);
2926 
2927         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
2928         FileUtils.writeLines(file, "US-ASCII", list);
2929 
2930         final String expected = "hello" + System.lineSeparator() + "world" + System.lineSeparator() +
2931                 System.lineSeparator() + "this is" + System.lineSeparator() +
2932                 System.lineSeparator() + "some text" + System.lineSeparator();
2933         final String actual = FileUtils.readFileToString(file, "US-ASCII");
2934         assertEquals(expected, actual);
2935     }
2936 
2937     @Test
2938     public void testWriteLines_3argsWithAppendOptionFalse_ShouldDeletePreviousFileLines() throws Exception {
2939         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
2940         FileUtils.writeStringToFile(file, "This line was there before you...");
2941 
2942         final List<String> linesToAppend = Arrays.asList("my first line", "The second Line");
2943         FileUtils.writeLines(file, linesToAppend, false);
2944 
2945         final String expected = "my first line"
2946                 + System.lineSeparator() + "The second Line"
2947                 + System.lineSeparator();
2948         final String actual = FileUtils.readFileToString(file);
2949         assertEquals(expected, actual);
2950     }
2951 
2952     @Test
2953     public void testWriteLines_3argsWithAppendOptionTrue_ShouldNotDeletePreviousFileLines() throws Exception {
2954         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
2955         FileUtils.writeStringToFile(file, "This line was there before you...");
2956 
2957         final List<String> linesToAppend = Arrays.asList("my first line", "The second Line");
2958         FileUtils.writeLines(file, linesToAppend, true);
2959 
2960         final String expected = "This line was there before you..."
2961                 + "my first line"
2962                 + System.lineSeparator() + "The second Line"
2963                 + System.lineSeparator();
2964         final String actual = FileUtils.readFileToString(file);
2965         assertEquals(expected, actual);
2966     }
2967 
2968     @Test
2969     public void testWriteLines_4arg() throws Exception {
2970         final Object[] data = {
2971                 "hello", new StringBuffer("world"), "", "this is", null, "some text"};
2972         final List<Object> list = Arrays.asList(data);
2973 
2974         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
2975         FileUtils.writeLines(file, "US-ASCII", list, "*");
2976 
2977         final String expected = "hello*world**this is**some text*";
2978         final String actual = FileUtils.readFileToString(file, "US-ASCII");
2979         assertEquals(expected, actual);
2980     }
2981 
2982     @Test
2983     public void testWriteLines_4arg_nullSeparator() throws Exception {
2984         final Object[] data = {
2985                 "hello", new StringBuffer("world"), "", "this is", null, "some text"};
2986         final List<Object> list = Arrays.asList(data);
2987 
2988         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
2989         FileUtils.writeLines(file, "US-ASCII", list, null);
2990 
2991         final String expected = "hello" + System.lineSeparator() + "world" + System.lineSeparator() +
2992                 System.lineSeparator() + "this is" + System.lineSeparator() +
2993                 System.lineSeparator() + "some text" + System.lineSeparator();
2994         final String actual = FileUtils.readFileToString(file, "US-ASCII");
2995         assertEquals(expected, actual);
2996     }
2997 
2998     @Test
2999     public void testWriteLines_4arg_Writer_nullData() throws Exception {
3000         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
3001         FileUtils.writeLines(file, "US-ASCII", null, "*");
3002 
3003         assertEquals(0, file.length(), "Sizes differ");
3004     }
3005 
3006     @Test
3007     public void testWriteLines_4argsWithAppendOptionFalse_ShouldDeletePreviousFileLines() throws Exception {
3008         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
3009         FileUtils.writeStringToFile(file, "This line was there before you...");
3010 
3011         final List<String> linesToAppend = Arrays.asList("my first line", "The second Line");
3012         FileUtils.writeLines(file, linesToAppend, null, false);
3013 
3014         final String expected = "my first line"
3015                 + System.lineSeparator() + "The second Line"
3016                 + System.lineSeparator();
3017         final String actual = FileUtils.readFileToString(file);
3018         assertEquals(expected, actual);
3019     }
3020 
3021     @Test
3022     public void testWriteLines_4argsWithAppendOptionTrue_ShouldNotDeletePreviousFileLines() throws Exception {
3023         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
3024         FileUtils.writeStringToFile(file, "This line was there before you...");
3025 
3026         final List<String> linesToAppend = Arrays.asList("my first line", "The second Line");
3027         FileUtils.writeLines(file, linesToAppend, null, true);
3028 
3029         final String expected = "This line was there before you..."
3030                 + "my first line"
3031                 + System.lineSeparator() + "The second Line"
3032                 + System.lineSeparator();
3033         final String actual = FileUtils.readFileToString(file);
3034         assertEquals(expected, actual);
3035     }
3036 
3037     @Test
3038     public void testWriteLines_5argsWithAppendOptionFalse_ShouldDeletePreviousFileLines() throws Exception {
3039         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
3040         FileUtils.writeStringToFile(file, "This line was there before you...");
3041 
3042         final List<String> linesToAppend = Arrays.asList("my first line", "The second Line");
3043         FileUtils.writeLines(file, null, linesToAppend, null, false);
3044 
3045         final String expected = "my first line"
3046                 + System.lineSeparator() + "The second Line"
3047                 + System.lineSeparator();
3048         final String actual = FileUtils.readFileToString(file);
3049         assertEquals(expected, actual);
3050     }
3051 
3052     @Test
3053     public void testWriteLines_5argsWithAppendOptionTrue_ShouldNotDeletePreviousFileLines() throws Exception {
3054         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
3055         FileUtils.writeStringToFile(file, "This line was there before you...");
3056 
3057         final List<String> linesToAppend = Arrays.asList("my first line", "The second Line");
3058         FileUtils.writeLines(file, null, linesToAppend, null, true);
3059 
3060         final String expected = "This line was there before you..."
3061                 + "my first line"
3062                 + System.lineSeparator() + "The second Line"
3063                 + System.lineSeparator();
3064         final String actual = FileUtils.readFileToString(file);
3065         assertEquals(expected, actual);
3066     }
3067 
3068     @Test
3069     public void testWriteLinesEncoding_WithAppendOptionFalse_ShouldDeletePreviousFileLines() throws Exception {
3070         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
3071         FileUtils.writeStringToFile(file, "This line was there before you...");
3072 
3073         final List<String> linesToAppend = Arrays.asList("my first line", "The second Line");
3074         FileUtils.writeLines(file, null, linesToAppend, false);
3075 
3076         final String expected = "my first line"
3077                 + System.lineSeparator() + "The second Line"
3078                 + System.lineSeparator();
3079         final String actual = FileUtils.readFileToString(file);
3080         assertEquals(expected, actual);
3081     }
3082 
3083     @Test
3084     public void testWriteLinesEncoding_WithAppendOptionTrue_ShouldNotDeletePreviousFileLines() throws Exception {
3085         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
3086         FileUtils.writeStringToFile(file, "This line was there before you...");
3087 
3088         final List<String> linesToAppend = Arrays.asList("my first line", "The second Line");
3089         FileUtils.writeLines(file, null, linesToAppend, true);
3090 
3091         final String expected = "This line was there before you..."
3092                 + "my first line"
3093                 + System.lineSeparator() + "The second Line"
3094                 + System.lineSeparator();
3095         final String actual = FileUtils.readFileToString(file);
3096         assertEquals(expected, actual);
3097     }
3098 
3099     @Test
3100     public void testWriteStringToFile_WithAppendOptionFalse_ShouldDeletePreviousFileLines() throws Exception {
3101         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
3102         FileUtils.writeStringToFile(file, "This line was there before you...");
3103 
3104         FileUtils.writeStringToFile(file, "this is brand new data", false);
3105 
3106         final String expected = "this is brand new data";
3107         final String actual = FileUtils.readFileToString(file);
3108         assertEquals(expected, actual);
3109     }
3110 
3111     @Test
3112     public void testWriteStringToFile_WithAppendOptionTrue_ShouldNotDeletePreviousFileLines() throws Exception {
3113         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
3114         FileUtils.writeStringToFile(file, "This line was there before you...");
3115 
3116         FileUtils.writeStringToFile(file, "this is brand new data", true);
3117 
3118         final String expected = "This line was there before you..."
3119                 + "this is brand new data";
3120         final String actual = FileUtils.readFileToString(file);
3121         assertEquals(expected, actual);
3122     }
3123 
3124     @Test
3125     public void testWriteStringToFileIntoNonExistentSubdir() throws Exception {
3126         final File file = new File(tempDirFile, "subdir/write.txt");
3127         FileUtils.writeStringToFile(file, "Hello /u1234", (Charset) null);
3128         final byte[] text = "Hello /u1234".getBytes();
3129         TestUtils.assertEqualContent(text, file);
3130     }
3131 
3132     /**
3133      * Requires admin privileges on Windows.
3134      *
3135      * @throws Exception For example java.nio.file.FileSystemException:
3136      *                   C:\Users\you\AppData\Local\Temp\junit2324629522183300191\FileUtilsTest8613879743106252609\symlinked-dir: A required privilege is
3137      *                   not held by the client.
3138      */
3139     @Test
3140     public void testWriteStringToFileIntoSymlinkedDir() throws Exception {
3141         final Path symlinkDir = createTempSymlinkedRelativeDir();
3142 
3143         final File file = symlinkDir.resolve("file").toFile();
3144         FileUtils.writeStringToFile(file, "Hello /u1234", StandardCharsets.UTF_8);
3145 
3146         final byte[] text = "Hello /u1234".getBytes();
3147         TestUtils.assertEqualContent(text, file);
3148     }
3149 
3150     @Test
3151     public void testWriteStringToFileWithCharset() throws Exception {
3152         final File file = new File(tempDirFile, "write.txt");
3153         FileUtils.writeStringToFile(file, "Hello /u1234", "UTF8");
3154         final byte[] text = "Hello /u1234".getBytes(StandardCharsets.UTF_8);
3155         TestUtils.assertEqualContent(text, file);
3156     }
3157 
3158     @Test
3159     public void testWriteStringToFileWithEncoding_WithAppendOptionFalse_ShouldDeletePreviousFileLines() throws Exception {
3160         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
3161         FileUtils.writeStringToFile(file, "This line was there before you...");
3162 
3163         FileUtils.writeStringToFile(file, "this is brand new data", (String) null, false);
3164 
3165         final String expected = "this is brand new data";
3166         final String actual = FileUtils.readFileToString(file);
3167         assertEquals(expected, actual);
3168     }
3169 
3170     @Test
3171     public void testWriteStringToFileWithEncoding_WithAppendOptionTrue_ShouldNotDeletePreviousFileLines() throws Exception {
3172         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
3173         FileUtils.writeStringToFile(file, "This line was there before you...");
3174 
3175         FileUtils.writeStringToFile(file, "this is brand new data", (String) null, true);
3176 
3177         final String expected = "This line was there before you..."
3178                 + "this is brand new data";
3179         final String actual = FileUtils.readFileToString(file);
3180         assertEquals(expected, actual);
3181     }
3182 
3183     @Test
3184     public void testWriteStringToFileWithNullCharset() throws Exception {
3185         final File file = new File(tempDirFile, "write.txt");
3186         FileUtils.writeStringToFile(file, "Hello /u1234", (Charset) null);
3187         final byte[] text = "Hello /u1234".getBytes();
3188         TestUtils.assertEqualContent(text, file);
3189     }
3190 
3191     @Test
3192     public void testWriteStringToFileWithNullStringCharset() throws Exception {
3193         final File file = new File(tempDirFile, "write.txt");
3194         FileUtils.writeStringToFile(file, "Hello /u1234", (String) null);
3195         final byte[] text = "Hello /u1234".getBytes();
3196         TestUtils.assertEqualContent(text, file);
3197     }
3198 
3199     @Test
3200     public void testWriteWithEncoding_WithAppendOptionFalse_ShouldDeletePreviousFileLines() throws Exception {
3201         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
3202         FileUtils.writeStringToFile(file, "This line was there before you...");
3203 
3204         FileUtils.write(file, "this is brand new data", (String) null, false);
3205 
3206         final String expected = "this is brand new data";
3207         final String actual = FileUtils.readFileToString(file);
3208         assertEquals(expected, actual);
3209     }
3210 
3211     @Test
3212     public void testWriteWithEncoding_WithAppendOptionTrue_ShouldNotDeletePreviousFileLines() throws Exception {
3213         final File file = TestUtils.newFile(tempDirFile, "lines.txt");
3214         FileUtils.writeStringToFile(file, "This line was there before you...");
3215 
3216         FileUtils.write(file, "this is brand new data", (String) null, true);
3217 
3218         final String expected = "This line was there before you..."
3219                 + "this is brand new data";
3220         final String actual = FileUtils.readFileToString(file);
3221         assertEquals(expected, actual);
3222     }
3223 
3224 }
3225