42
File file = new File(path);
if (!file.delete())
{
    throw new IOException(
        "Failed to delete the file because: " +
        getReasonForFileDeletionFailureInPlainEnglish(file));
}

Is there a good implementation of getReasonForFileDeletionFailureInPlainEnglish(file) already out there? Or else I'll just have to write it myself.

Greg Mattes
  • 33,090
  • 15
  • 73
  • 105
Arne Evertsson
  • 19,693
  • 20
  • 69
  • 84

6 Answers6

28

In Java 6, there is unfortunately no way to determine why a file cannot be deleted. With Java 7, you can use java.nio.file.Files#delete() instead, which will give you a detailed cause of the failure, if the file or directory cannot be deleted.

Note that file.list() may return entries for directories, which can be deleted. The API documentation for delete says that only empty directories can be deleted, but a directory is considered empty, if the contained files are e.g. OS specific metadata files.

Reinhold
  • 546
  • 1
  • 3
  • 14
jarnbjo
  • 33,923
  • 7
  • 70
  • 94
  • 11
    This delete method does not seem to exist in Java 7 API. [link](http://download.oracle.com/javase/7/docs/api/java/nio/file/Path.html) Edit: just found it it is now in the Files class. [link](http://download.oracle.com/javase/7/docs/api/java/nio/file/Files.html) – RishiD Sep 10 '11 at 01:07
  • Does it throw when _a file_ fails to be deleted ? Return type is void ! Its docs are unclear. Asked here : http://stackoverflow.com/questions/19935624/java-nio-file-files-deletepath-path-void-return-type – Mr_and_Mrs_D Nov 12 '13 at 20:28
22

Hmm, best I could do:

public String getReasonForFileDeletionFailureInPlainEnglish(File file) {
    try {
        if (!file.exists())
            return "It doesn't exist in the first place.";
        else if (file.isDirectory() && file.list().length > 0)
            return "It's a directory and it's not empty.";
        else
            return "Somebody else has it open, we don't have write permissions, or somebody stole my disk.";
    } catch (SecurityException e) {
        return "We're sandboxed and don't have filesystem access.";
    }
}
Cory Petosky
  • 12,458
  • 3
  • 39
  • 44
  • @Cory, file.exists(), isDirectory() and list() can all throw SecurityExcepions. – Bob Cross Nov 13 '09 at 13:06
  • @Bob: That only happens in a sandbox. And the original delete() would most likely also have thrown a SecurityException. But for completeness, I suppose he should catch it (and return "sandboxed: no file system access") – Thilo Nov 13 '09 at 13:10
  • @Thilo added, but yeah, I was addressing the question asked, not every other possibility when engaging in file I/O. :) – Cory Petosky Nov 13 '09 at 13:13
10

Be aware that it can be your own application that prevents a file from being deleted!

If you wrote to the file previously and didn't close the writer, you are locking the file yourself.

xastor
  • 482
  • 5
  • 17
  • 2
    When testing on Windows 7 using Java 6 I had this problem with a reader as well. I tried deleting the file before closing the reader and it failed. – Doppelganger Jul 15 '15 at 16:31
10

Java 7 java.nio.file.Files class can be also used:

http://docs.oracle.com/javase/tutorial/essential/io/delete.html

try {
    Files.delete(path);
} catch (NoSuchFileException x) {
    System.err.format("%s: no such" + " file or directory%n", path);
} catch (DirectoryNotEmptyException x) {
    System.err.format("%s not empty%n", path);
} catch (IOException x) {
    // File permission problems are caught here.
    System.err.println(x);
}
Quark
  • 1,578
  • 2
  • 19
  • 34
5

A deletion may fail due to one or more reasons:

  1. File does not exist (use File#exists() to test).
  2. File is locked (because it is opened by another app (or your own code!).
  3. You are not authorized (but that would have thrown a SecurityException, not returned false!).

So whenever deletion fails, do a File#exists() to check if it is caused by 1) or 2).

Summarized:

if (!file.delete()) {
    String message = file.exists() ? "is in use by another app" : "does not exist";
    throw new IOException("Cannot delete file, because file " + message + ".");
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • @BalusC, remember that file.exists() can also throw a SecurityException. – Bob Cross Nov 13 '09 at 13:06
  • You will not get a SecurityException if the delete fails because of file system permissions. – Thilo Nov 13 '09 at 13:06
  • You will only get SecurityException if your JVM is configured restrictively, for example if you are an applet. A "normal" application would not be sandboxed here. – Thilo Nov 13 '09 at 13:08
  • @Bob: Then just wrap it all in a try/catch block on `SecurityException`. @Thilo: I didn't said anything about file system permissions. Just about an authorization failure at any level. – BalusC Nov 13 '09 at 13:12
-1

As pointed out in File.delete()

you may use a SecurityManager that throws the exeception for you.

ba__friend
  • 5,783
  • 2
  • 27
  • 20