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:
- "If a security manager exists and its
checkWrite()
method does not permit the named directory to be created" then a SecurityException
will be thrown.
- 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:
- You need to inspect the boolean result from this method. If you ignore the result the operation could silently fail.
- 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.
- 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.");
}