views:

254

answers:

2

What is the most succinct way to create a directory called "Foo" underneath the current working directory of my Java application (if it does not already exist)?

Or, a slightly different angle: What is the Java equivalent of Directory.CreateDirectory("Foo") in .NET?

+3  A: 

The java.io package does not have a Directory class, but you can use the mkdir() method on the File class instead:

(new File("Foo")).mkdir()

Note that mkdir() has two separate failure modes:

  1. "If a security manager exists and its checkWrite() method does not permit the named directory to be created" then a SecurityException will be thrown.
  2. If the operation fails for another reason, mkdir() will return false. (More specifically, it will return true if and only if the directory was created.)

Point 1 is ok — if you don't have permission, throw. Point 2 is a little sub-optimal for three reasons:

  1. You need to inspect the boolean result from this method. If you ignore the result the operation could silently fail.
  2. If you get a false return you have no idea why the operation failed, which makes it difficult to recover, or formulate a meaningful error message.
  3. The strict "if and only if" wording of the contract also means that the method returns false if the directory already exists.

Aside: Contrast Point 3 with the behaviour of the .NET Directory.CreateDirectory() which does nothing if the directory exists. This kind of makes sense — "create a directory"; "ok, the directory is created". Does it matter if it was created now or earlier; by this process or another? If you really cared about that wouldn't you be asking a different question: "Does this directory exist?"

The next caveat is that mkdir() will not create more than one directory at a time. For my simple example of a directory named "Foo" this is fine; however, if you wanted to create a directory called Bar within the directory Foo (i.e. to create the directory "Foo/Bar") you must remember to use the mkdirs() method instead.

So to work around all of these caveats, you can employ a helper method such as the following:

public static File createDirectory(String directoryPath) throws IOException {
    File dir = new File(directoryPath);
    if (dir.exists()) {
        return dir;
    }
    if (dir.mkdirs()) {
        return dir;
    }
    throw new IOException("Failed to create directory '" + dir.getAbsolutePath() + "' for an unknown reason.");
}
Daniel Fortunov
You asked a question and immediately posted your own answer ?
Brian Agnew
Seen that before, the idea is that the user who posts the question+answer combination wants to present a thorough answer to some question which may seem simple in a context which will direct those people who do not yet know how to do it to his own answer. Perfectly acceptable in my opinion although a bit confusing.
Esko
Ah, so now I know how the "Blog" part of Stackoverflow's vision (http://sstatic.net/so/Img/stackoverflow-venn-diagram.png) comes from :)
sfussenegger
+1  A: 

I've seen a slightly more concise form of your createDirectory method:

File f = new File(xyz);
if (!f.exists() && !f.mkdirs()) throw new IOException("Could not create directory " + f);

It might also be worthwhile to check if f exists but is not a directory.

Sam Barnum