Reputation: 27050
If I call one of the methods File.mkdir()
or File.mkdirs()
in Java, and it returns false
, is there a way to know why was the directory not created?
Upvotes: 13
Views: 10623
Reputation: 1684
I had a mkdirs() failure on windows on a UNC path. The code looks like this:
public File getOldDirectoryPath(String root, String name)
{
File fulldir = new File(root, name)
boolean created = false
int retry = 0
while (!created) {
retry++
if (!(created = fulldir.exists())) {
if (20 == retry) break
if (!fulldir.mkdirs()) {
sleep(100)
fulldir = new File(root, name)
}
}
}
return fulldir.exists() ? fulldir : null
}
There appears to be some sort of caching involved where exists() returns false (does not exists) but the mkdir on the file system fails because it does exist. Recreating the File() entry or lengthing the timeout did not make a difference.
I discovered a plugin on elasticsearch to fix a SMB problem on Windows. Researching the solution, it uses nio.file instead of io.File. Rewriting the function fixed the issue:
public File getDirectoryPath(String root, String name)
{
Path fulldir = Paths.get(root, name)
boolean created = false
int retry = 0
while (!created) {
retry++
if (!(created = Files.isDirectory(fulldir))) {
if (20 == retry) break
try {
Files.createDirectories(fulldir)
} catch (Throwable thx) {
// error handling
}
}
}
return fulldir.toFile()
}
createDirectories() sometimes fail, but recovers where mkdirs() does not.
Upvotes: 1
Reputation: 33954
Not really, no. If a SecurityException
is NOT thrown, then the most likely cause is a typo in the path, meaning you've accidentally specified a parent path to the new directories that is somehow invalid.
I don't suppose you have it wrapped in a try { ... } catch (Exception e)
block, where you don't realize a SecurityException
is being thrown, because you're catching an ancestor of SecurityException
, do you?
If you have a high belief that everything looks right, and it still fails, I suppose you could simply put it in a loop to retry, say, three times. If it still fails, and depending on your application, you might raise some kind of alert at the UI level, or log the error in a log file (assuming you can write to it).
I suppose it's possible that some deeper I/O issue is preventing it from working, but beyond simply notifying the user of a failure there isn't much you can (or really should) do at an application level. If there's something deeper in the I/O wrong, that's more likely a problem with the system/hardware/OS, or something completely wonky that you have no control over like a subsystem/service crash.
...and if that's happening, that's the responsibility of the IT guy to fix, not your application. Unless of course your app is somehow causing the crash.
Upvotes: 3