Skip to content

Commit 4c14c07

Browse files
committed
[IO-859] FileUtils.forceDelete on non-existent file on Windows throws
IOException rather than FileNotFoundException
1 parent 8dff97b commit 4c14c07

File tree

4 files changed

+12
-8
lines changed

4 files changed

+12
-8
lines changed

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ The <action> type attribute can be add,update,fix,remove.
5454
<action dev="ggregory" type="fix" due-to="Gary Gregory">Fix implicit narrowing conversion in compound assignment in UnsynchronizedBufferedReader.skip(long).</action>
5555
<action dev="ggregory" type="fix" issue="IO-860" due-to="Stefan Feenstra, Gary Gregory">Missing reserved file names in FileSystem.WINDOWS (superscript digits for COM and LPT).</action>
5656
<action dev="ggregory" type="fix" issue="IO-856" due-to="Thomas Hartwig, Gary Gregory">FileUtils.listFiles(final File, String[], boolean) can throw NoSuchFileException #697, #699.</action>
57+
<action dev="ggregory" type="fix" issue="IO-859" due-to="JD Dean, Gary Gregory">FileUtils.forceDelete on non-existent file on Windows throws IOException rather than FileNotFoundException.</action>
5758
<!-- ADD -->
5859
<action dev="ggregory" type="add" due-to="Gary Gregory">Add @FunctionalInterface to ClassNameMatcher.</action>
5960
<action dev="ggregory" type="add" due-to="Gary Gregory">Add ValidatingObjectInputStream.Builder and ValidatingObjectInputStream.builder().</action>

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import java.nio.file.FileVisitResult;
4343
import java.nio.file.Files;
4444
import java.nio.file.LinkOption;
45+
import java.nio.file.NoSuchFileException;
4546
import java.nio.file.NotDirectoryException;
4647
import java.nio.file.Path;
4748
import java.nio.file.StandardCopyOption;
@@ -1384,12 +1385,13 @@ private static void doCopyDirectory(final File srcDir, final File destDir, final
13841385
*/
13851386
public static void forceDelete(final File file) throws IOException {
13861387
Objects.requireNonNull(file, PROTOCOL_FILE);
1387-
1388+
checkFileExists(file, file.getName()); // fail-fast
13881389
final Counters.PathCounters deleteCounters;
13891390
try {
1390-
deleteCounters = PathUtils.delete(
1391-
file.toPath(), PathUtils.EMPTY_LINK_OPTION_ARRAY,
1392-
StandardDeleteOption.OVERRIDE_READ_ONLY);
1391+
deleteCounters = PathUtils.delete(file.toPath(), PathUtils.EMPTY_LINK_OPTION_ARRAY, StandardDeleteOption.OVERRIDE_READ_ONLY);
1392+
} catch (final NoSuchFileException ex) {
1393+
// Map NIO to IO exception
1394+
throw new FileNotFoundException("Cannot delete file: " + file);
13931395
} catch (final IOException ex) {
13941396
throw new IOException("Cannot delete file: " + file, ex);
13951397
}

src/main/java/org/apache/commons/io/file/PathUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -559,9 +559,9 @@ public static PathCounters deleteFile(final Path file, final DeleteOption... del
559559
public static PathCounters deleteFile(final Path file, final LinkOption[] linkOptions, final DeleteOption... deleteOptions)
560560
throws NoSuchFileException, IOException {
561561
//
562-
// TODO Needs clean up
562+
// TODO Needs clean up?
563563
//
564-
if (Files.isDirectory(file, linkOptions)) {
564+
if (!Files.exists(file, linkOptions) || Files.isDirectory(file, linkOptions)) {
565565
throw new NoSuchFileException(file.toString());
566566
}
567567
final PathCounters pathCounts = Counters.longPathCounters();

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static org.junit.jupiter.api.Assertions.assertNull;
2525
import static org.junit.jupiter.api.Assertions.assertSame;
2626
import static org.junit.jupiter.api.Assertions.assertThrows;
27+
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
2728
import static org.junit.jupiter.api.Assertions.assertTrue;
2829
import static org.junit.jupiter.api.Assertions.fail;
2930
import static org.junit.jupiter.api.Assumptions.assumeFalse;
@@ -1647,10 +1648,10 @@ public void testForceDeleteAFile2() throws Exception {
16471648
}
16481649

16491650
@Test
1650-
public void testForceDeleteAFile3() {
1651+
public void testForceDeleteAFileDoesNotExist() {
16511652
final File destination = new File(tempDirFile, "no_such_file");
16521653
assertFalse(destination.exists(), "Check No Exist");
1653-
assertThrows(IOException.class, () -> FileUtils.forceDelete(destination));
1654+
assertThrowsExactly(FileNotFoundException.class, () -> FileUtils.forceDelete(destination));
16541655

16551656
}
16561657

0 commit comments

Comments
 (0)