Question

I have a situation where I need to run a "pre-check" to see if a directory is "createable". This is not a problem, just run a file.mkdirs() and see if it returns true.

The problem is that I would like to clean up after this check. This is a bit tricky, because I want to delete only those folders and subfolder that mkdirs() actually created.

Can anyone think of a clever way to do this?

Was it helpful?

Solution

I think this method does the job without you having to call mkdirs:

public static boolean canMkdirs(File dir) {
    if(dir == null || dir.exists())
        return false;
    File parent = null;
    try {
        parent = dir.getCanonicalFile().getParentFile();
        while(!parent.exists())
            parent = parent.getParentFile();
    } catch(NullPointerException | IOException e) {
        return false;
    }
    return parent.isDirectory() && parent.canWrite();
}

OTHER TIPS

Keep one array which holds name of that dirs. so when you want to delete dir you can take that array content/string/dir-name to delete.

A bit dangerous:

if (file.mkdirs()) {
    long t0 = file.lastModified();
    for (;;) {
        long t = file.lastModified();
        if (t < t0 - 1000L) { // Created longer than it's child minus 1 s?
            break;
        }
        t0 = t;
        file.delete();
        file = file.getParentFile();
    }
}

If my assumption that permissions are inherited in the file structure is correct, something like this should do it:

File f = new File("C:\\doesntExist\\Nope\\notHere");
File tempFile = f;
while (!tempFile.exists())
   tempFile = tempFile.getParentFile();
if (!tempFile.canWrite()
    && tempFile.isDirectory()) // Copied this line from Lone nebula's answer (don't tell anyone, ok?)
   System.out.println("Can't write!");
else
{
   f.mkdirs();
   ...
}

Judging by the mkdirs() source code:

public boolean mkdirs() {
       if (exists()) {
           return false;
        }
        if (mkdir()) {
            return true;
       }
       File canonFile = null;
       try {
            canonFile = getCanonicalFile();
        } catch (IOException e) {
            return false;
        }

        File parent = canonFile.getParentFile();
        return (parent != null && (parent.mkdirs() || parent.exists()) &&
                canonFile.mkdir());
    }

If I hadn't missed something you have two options:

  • remeber the state of the files on the disk before calling the mkdirs(), compare it with the state after the mkdirs(), handle if necessary
  • extend the File class and override mkdirs() method to remember exactly which files were created. If any are created, handle them.

The latter seems like a more elegant solution which will yield less code.

UPDATE:

I strongly recommend to take in consideration david a. comment.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top