Skip to content

Commit 33db634

Browse files
authored
[IO-808] Rationalize and unify checking for existence of files and directories (#529)
* Rationalize and unify checking for existence of files and directories * fix sizeOfDirectoryAsBigInteger
1 parent 29dc5ea commit 33db634

3 files changed

Lines changed: 67 additions & 97 deletions

File tree

src/main/java/org/apache/commons/io/FileUtils.java

Lines changed: 55 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -292,13 +292,12 @@ public static String byteCountToDisplaySize(final Number size) {
292292
* @return the checksum specified, updated with the content of the file
293293
* @throws NullPointerException if the given {@link File} is {@code null}.
294294
* @throws NullPointerException if the given {@link Checksum} is {@code null}.
295-
* @throws IllegalArgumentException if the given {@link File} does not exist or is not a file.
295+
* @throws IllegalArgumentException if the given {@link File} is not a file.
296296
* @throws IOException if an IO error occurs reading the file.
297297
* @since 1.3
298298
*/
299299
public static Checksum checksum(final File file, final Checksum checksum) throws IOException {
300-
requireExistsChecked(file, "file");
301-
requireFile(file, "file");
300+
checkFileExists(file, "file");
302301
Objects.requireNonNull(checksum, "checksum");
303302
try (InputStream inputStream = new CheckedInputStream(Files.newInputStream(file.toPath()), checksum)) {
304303
IOUtils.consume(inputStream);
@@ -378,8 +377,8 @@ public static boolean contentEquals(final File file1, final File file2) throws I
378377
return true;
379378
}
380379

381-
requireFile(file1, "file1");
382-
requireFile(file2, "file2");
380+
checkFileExists(file1, "file1");
381+
checkFileExists(file2, "file2");
383382

384383
if (file1.length() != file2.length()) {
385384
// lengths differ, cannot be equal
@@ -431,8 +430,8 @@ public static boolean contentEqualsIgnoreEOL(final File file1, final File file2,
431430
return true;
432431
}
433432

434-
requireFile(file1, "file1");
435-
requireFile(file2, "file2");
433+
checkFileExists(file1, "file1");
434+
checkFileExists(file2, "file2");
436435

437436
if (file1.getCanonicalFile().equals(file2.getCanonicalFile())) {
438437
// same file
@@ -665,7 +664,7 @@ public static void copyDirectory(final File srcDir, final File destDir, final Fi
665664
public static void copyDirectory(final File srcDir, final File destDir, final FileFilter fileFilter, final boolean preserveFileDate,
666665
final CopyOption... copyOptions) throws IOException {
667666
requireFileCopy(srcDir, destDir);
668-
requireDirectory(srcDir, "srcDir");
667+
requireDirectoryExists(srcDir, "srcDir");
669668
requireCanonicalPathsNotEquals(srcDir, destDir);
670669

671670
// Cater for destination being directory within the source directory (see IO-141)
@@ -797,11 +796,12 @@ public static void copyFile(final File srcFile, final File destFile, final boole
797796
*/
798797
public static void copyFile(final File srcFile, final File destFile, final boolean preserveFileDate, final CopyOption... copyOptions) throws IOException {
799798
requireFileCopy(srcFile, destFile);
800-
requireFile(srcFile, "srcFile");
799+
checkFileExists(srcFile, "srcFile");
801800
requireCanonicalPathsNotEquals(srcFile, destFile);
802801
createParentDirectories(destFile);
803-
requireFileIfExists(destFile, "destFile");
802+
Objects.requireNonNull(destFile, "destFile");
804803
if (destFile.exists()) {
804+
checkFileExists(destFile, "destFile");
805805
requireCanWrite(destFile, "destFile");
806806
}
807807
Files.copy(srcFile.toPath(), destFile.toPath(), copyOptions);
@@ -1259,8 +1259,8 @@ public static boolean deleteQuietly(final File file) {
12591259
* @param child the file to consider as the child.
12601260
* @return true is the candidate leaf is under by the specified composite. False otherwise.
12611261
* @throws IOException if an IO error occurs while checking the files.
1262-
* @throws NullPointerException if the given {@link File} is {@code null}.
1263-
* @throws IllegalArgumentException if the given {@link File} does not exist or is not a directory.
1262+
* @throws NullPointerException if the parent is {@code null}.
1263+
* @throws IllegalArgumentException if the parent is not a directory.
12641264
* @see FilenameUtils#directoryContains(String, String)
12651265
* @since 2.2
12661266
*/
@@ -1657,10 +1657,9 @@ public static boolean isFileNewer(final File file, final Date date) {
16571657
* @return true if the {@link File} exists and has been modified more
16581658
* recently than the reference {@link File}.
16591659
* @throws NullPointerException if the file or reference file is {@code null}.
1660-
* @throws IllegalArgumentException if the reference file doesn't exist.
1660+
* @throws UncheckedIOException if the reference file doesn't exist.
16611661
*/
16621662
public static boolean isFileNewer(final File file, final File reference) {
1663-
requireExists(reference, "reference");
16641663
return Uncheck.get(() -> PathUtils.isNewer(file.toPath(), reference.toPath()));
16651664
}
16661665

@@ -1862,8 +1861,7 @@ public static boolean isFileOlder(final File file, final Date date) {
18621861
* @throws NullPointerException if the file or reference file is {@code null}.
18631862
* @throws IllegalArgumentException if the reference file doesn't exist.
18641863
*/
1865-
public static boolean isFileOlder(final File file, final File reference) {
1866-
requireExists(reference, "reference");
1864+
public static boolean isFileOlder(final File file, final File reference) throws FileNotFoundException {
18671865
return Uncheck.get(() -> PathUtils.isOlder(file.toPath(), reference.toPath()));
18681866
}
18691867

@@ -2307,7 +2305,7 @@ private static File mkdirs(final File directory) throws IOException {
23072305
*/
23082306
public static void moveDirectory(final File srcDir, final File destDir) throws IOException {
23092307
validateMoveParameters(srcDir, destDir);
2310-
requireDirectory(srcDir, "srcDir");
2308+
requireDirectoryExists(srcDir, "srcDir");
23112309
requireAbsent(destDir, "destDir");
23122310
if (!srcDir.renameTo(destDir)) {
23132311
if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath() + File.separator)) {
@@ -2394,7 +2392,7 @@ public static void moveFile(final File srcFile, final File destFile) throws IOEx
23942392
*/
23952393
public static void moveFile(final File srcFile, final File destFile, final CopyOption... copyOptions) throws IOException {
23962394
validateMoveParameters(srcFile, destFile);
2397-
requireFile(srcFile, "srcFile");
2395+
checkFileExists(srcFile, "srcFile");
23982396
requireAbsent(destFile, "destFile");
23992397
final boolean rename = srcFile.renameTo(destFile);
24002398
if (!rename) {
@@ -2431,8 +2429,7 @@ public static void moveFileToDirectory(final File srcFile, final File destDir, f
24312429
if (!destDir.exists() && createDestDir) {
24322430
mkdirs(destDir);
24332431
}
2434-
requireExistsChecked(destDir, "destDir");
2435-
requireDirectory(destDir, "destDir");
2432+
requireDirectoryExists(destDir, "destDir");
24362433
moveFile(srcFile, new File(destDir, srcFile.getName()));
24372434
}
24382435

@@ -2558,7 +2555,7 @@ public static FileOutputStream openOutputStream(final File file) throws IOExcept
25582555
public static FileOutputStream openOutputStream(final File file, final boolean append) throws IOException {
25592556
Objects.requireNonNull(file, "file");
25602557
if (file.exists()) {
2561-
requireFile(file, "file");
2558+
checkFileExists(file, "file");
25622559
requireCanWrite(file, "file");
25632560
} else {
25642561
createParentDirectories(file);
@@ -2721,81 +2718,52 @@ private static void requireCanWrite(final File file, final String name) {
27212718
}
27222719

27232720
/**
2724-
* Requires that the given {@link File} is a directory.
2721+
* Requires that the given {@link File} exists and is a directory.
27252722
*
27262723
* @param directory The {@link File} to check.
27272724
* @param name The parameter name to use in the exception message in case of null input or if the file is not a directory.
2728-
* @return the given directory.
27292725
* @throws NullPointerException if the given {@link File} is {@code null}.
2730-
* @throws IllegalArgumentException if the given {@link File} does not exist or is not a directory.
2726+
* @throws FileNotFoundException if the given {@link File} does not exist
2727+
* @throws IllegalArgumentException if the given {@link File} is not a directory
27312728
*/
2732-
private static File requireDirectory(final File directory, final String name) {
2729+
private static void requireDirectoryExists(final File directory, final String name) throws FileNotFoundException {
27332730
Objects.requireNonNull(directory, name);
27342731
if (!directory.isDirectory()) {
2735-
throw new IllegalArgumentException("Parameter '" + name + "' is not a directory: '" + directory + "'");
2732+
if (directory.exists()) {
2733+
throw new IllegalArgumentException("Parameter '" + name + "' is not a directory: '" + directory + "'");
2734+
}
2735+
throw new FileNotFoundException("Directory '" + directory + "' does not exist.");
27362736
}
2737-
return directory;
2738-
}
2739-
2740-
/**
2741-
* Requires that the given {@link File} exists and is a directory.
2742-
*
2743-
* @param directory The {@link File} to check.
2744-
* @param name The parameter name to use in the exception message in case of null input.
2745-
* @return the given directory.
2746-
* @throws NullPointerException if the given {@link File} is {@code null}.
2747-
* @throws IllegalArgumentException if the given {@link File} does not exist or is not a directory.
2748-
*/
2749-
private static File requireDirectoryExists(final File directory, final String name) {
2750-
requireExists(directory, name);
2751-
requireDirectory(directory, name);
2752-
return directory;
27532737
}
27542738

27552739
/**
27562740
* Requires that the given {@link File} is a directory if it exists.
27572741
*
27582742
* @param directory The {@link File} to check.
27592743
* @param name The parameter name to use in the exception message in case of null input.
2760-
* @return the given directory.
2744+
* @throws FileNotFoundException if the given {@link File} does not exist
27612745
* @throws NullPointerException if the given {@link File} is {@code null}.
27622746
* @throws IllegalArgumentException if the given {@link File} exists but is not a directory.
27632747
*/
2764-
private static File requireDirectoryIfExists(final File directory, final String name) {
2748+
private static void requireDirectoryIfExists(final File directory, final String name) throws FileNotFoundException {
27652749
Objects.requireNonNull(directory, name);
27662750
if (directory.exists()) {
2767-
requireDirectory(directory, name);
2768-
}
2769-
return directory;
2770-
}
2771-
2772-
/**
2773-
* Requires that the given {@link File} exists and throws an {@link IllegalArgumentException} if it doesn't.
2774-
*
2775-
* @param file The {@link File} to check.
2776-
* @param fileParamName The parameter name to use in the exception message in case of {@code null} input.
2777-
* @return the given file.
2778-
* @throws NullPointerException if the given {@link File} is {@code null}.
2779-
* @throws IllegalArgumentException if the given {@link File} does not exist.
2780-
*/
2781-
private static File requireExists(final File file, final String fileParamName) {
2782-
Objects.requireNonNull(file, fileParamName);
2783-
if (!file.exists()) {
2784-
throw new IllegalArgumentException("File system element for parameter '" + fileParamName + "' does not exist: '" + file + "'");
2751+
requireDirectoryExists(directory, name);
27852752
}
2786-
return file;
27872753
}
27882754

27892755
/**
2790-
* Requires that the given {@link File} exists and throws an {@link FileNotFoundException} if it doesn't.
2756+
* Requires that the given {@link File} object, which may be a file or a directory,
2757+
* points to an actually existing item in the file system,
2758+
* and throws a {@link FileNotFoundException} if it doesn't.
27912759
*
27922760
* @param file The {@link File} to check.
27932761
* @param fileParamName The parameter name to use in the exception message in case of {@code null} input.
27942762
* @return the given file.
27952763
* @throws NullPointerException if the given {@link File} is {@code null}.
27962764
* @throws FileNotFoundException if the given {@link File} does not exist.
27972765
*/
2798-
private static File requireExistsChecked(final File file, final String fileParamName) throws FileNotFoundException {
2766+
private static File checkFileObjectExists(final File file, final String fileParamName) throws FileNotFoundException {
27992767
Objects.requireNonNull(file, fileParamName);
28002768
if (!file.exists()) {
28012769
throw new FileNotFoundException("File system element for parameter '" + fileParamName + "' does not exist: '" + file + "'");
@@ -2804,18 +2772,25 @@ private static File requireExistsChecked(final File file, final String fileParam
28042772
}
28052773

28062774
/**
2807-
* Requires that the given {@link File} is a file.
2775+
* Requires that the given {@link File} object,
2776+
* points to an actual file (not a directory) in the file system,
2777+
* and throws a {@link FileNotFoundException} if it doesn't.
2778+
* It throws an IllegalArgumentException if the object points to a directory.
28082779
*
28092780
* @param file The {@link File} to check.
28102781
* @param name The parameter name to use in the exception message.
28112782
* @return the given file.
2783+
* @throws FileNotFoundException if the file does not exist
28122784
* @throws NullPointerException if the given {@link File} is {@code null}.
2813-
* @throws IllegalArgumentException if the given {@link File} does not exist or is not a file.
2785+
* @throws IllegalArgumentException if the given {@link File} is not a file.
28142786
*/
2815-
private static File requireFile(final File file, final String name) {
2787+
private static File checkFileExists(final File file, final String name) throws FileNotFoundException {
28162788
Objects.requireNonNull(file, name);
28172789
if (!file.isFile()) {
2818-
throw new IllegalArgumentException("Parameter '" + name + "' is not a file: " + file);
2790+
if (file.exists()) {
2791+
throw new IllegalArgumentException("Parameter '" + name + "' is not a file: " + file);
2792+
}
2793+
throw new FileNotFoundException("Source '" + file + "' does not exist");
28192794
}
28202795
return file;
28212796
}
@@ -2829,24 +2804,10 @@ private static File requireFile(final File file, final String name) {
28292804
* @throws FileNotFoundException if the source does not exist.
28302805
*/
28312806
private static void requireFileCopy(final File source, final File destination) throws FileNotFoundException {
2832-
requireExistsChecked(source, "source");
2807+
checkFileObjectExists(source, "source");
28332808
Objects.requireNonNull(destination, "destination");
28342809
}
28352810

2836-
/**
2837-
* Requires that the given {@link File} is a file if it exists.
2838-
*
2839-
* @param file The {@link File} to check.
2840-
* @param name The parameter name to use in the exception message in case of null input.
2841-
* @return the given directory.
2842-
* @throws NullPointerException if the given {@link File} is {@code null}.
2843-
* @throws IllegalArgumentException if the given {@link File} exists but is not a directory.
2844-
*/
2845-
private static File requireFileIfExists(final File file, final String name) {
2846-
Objects.requireNonNull(file, name);
2847-
return file.exists() ? requireFile(file, name) : file;
2848-
}
2849-
28502811
/**
28512812
* Sets file lastModifiedTime, lastAccessTime and creationTime to match source file
28522813
*
@@ -2900,7 +2861,6 @@ private static boolean setTimes(final File sourceFile, final File targetFile) {
29002861
* @since 2.0
29012862
*/
29022863
public static long sizeOf(final File file) {
2903-
requireExists(file, "file");
29042864
return Uncheck.get(() -> PathUtils.sizeOf(file.toPath()));
29052865
}
29062866

@@ -2923,7 +2883,6 @@ public static long sizeOf(final File file) {
29232883
* @since 2.4
29242884
*/
29252885
public static BigInteger sizeOfAsBigInteger(final File file) {
2926-
requireExists(file, "file");
29272886
return Uncheck.get(() -> PathUtils.sizeOfAsBigInteger(file.toPath()));
29282887
}
29292888

@@ -2942,7 +2901,11 @@ public static BigInteger sizeOfAsBigInteger(final File file) {
29422901
* @throws UncheckedIOException if an IO error occurs.
29432902
*/
29442903
public static long sizeOfDirectory(final File directory) {
2945-
requireDirectoryExists(directory, "directory");
2904+
try {
2905+
requireDirectoryExists(directory, "directory");
2906+
} catch (FileNotFoundException e) {
2907+
throw new UncheckedIOException(e);
2908+
}
29462909
return Uncheck.get(() -> PathUtils.sizeOfDirectory(directory.toPath()));
29472910
}
29482911

@@ -2956,7 +2919,11 @@ public static long sizeOfDirectory(final File directory) {
29562919
* @since 2.4
29572920
*/
29582921
public static BigInteger sizeOfDirectoryAsBigInteger(final File directory) {
2959-
requireDirectoryExists(directory, "directory");
2922+
try {
2923+
requireDirectoryExists(directory, "directory");
2924+
} catch (FileNotFoundException e) {
2925+
throw new UncheckedIOException(e);
2926+
}
29602927
return Uncheck.get(() -> PathUtils.sizeOfDirectoryAsBigInteger(directory.toPath()));
29612928
}
29622929

src/test/java/org/apache/commons/io/FileUtilsDirectoryContainsTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static org.junit.jupiter.api.Assertions.assertTrue;
2222

2323
import java.io.File;
24+
import java.io.FileNotFoundException;
2425
import java.io.IOException;
2526

2627
import org.junit.jupiter.api.BeforeEach;
@@ -115,7 +116,7 @@ public void testDirectoryDoesNotContainsDirectory() throws IOException {
115116
public void testDirectoryDoesNotExist() {
116117
final File dir = new File("DOESNOTEXIST");
117118
assertFalse(dir.exists());
118-
assertThrows(IllegalArgumentException.class, () -> FileUtils.directoryContains(dir, file1));
119+
assertThrows(FileNotFoundException.class, () -> FileUtils.directoryContains(dir, file1));
119120
}
120121

121122
@Test
@@ -168,6 +169,6 @@ public void testUnrealizedContainment() {
168169
final File file = new File(dir, "DOESNOTEXIST2");
169170
assertFalse(dir.exists());
170171
assertFalse(file.exists());
171-
assertThrows(IllegalArgumentException.class, () -> FileUtils.directoryContains(dir, file));
172+
assertThrows(FileNotFoundException.class, () -> FileUtils.directoryContains(dir, file));
172173
}
173174
}

0 commit comments

Comments
 (0)