5

I need a directory to save files but I am not sure whether it exists.
So I need to check if it exists first, and create it if necessary.

File saveDir = new File("/tmp/appname/savedir/");
if(!saveDir.exists()){
    saveDir.mkdirs(); 
}

As above, there is a question.
Method "saveDir.exists()" returns a boolean value which indicates if the file path exists.

Of course, I could write some redundant and ugly code to work.

Is there a way to write some elegant code to achieve this goal?

WBT
  • 2,249
  • 3
  • 28
  • 40
kino lucky
  • 1,365
  • 4
  • 15
  • 24

8 Answers8

8

is your question about "redundant" check-directory-exist code, or you need to create a directory and all missing parent directory?

I believe both can be easily done by using FileUtils in Apache Commons IO:

FileUtils.forceMkDir(new File("/some/missing/parent/directory/foo"));
Adrian Shum
  • 38,812
  • 10
  • 83
  • 131
6

There is always

if(!file.exists() && !file.mkDirs()) { // handle the failed to create situation... }
Nathaniel
  • 457
  • 5
  • 14
3

Elegance is more a subjective thing, but if you want to check whether the directories are actually created, check also the return value of File.mkdirs(). If it returns false it depends on your application on how to handle it (e.g. throw an exception).

Stephan
  • 7,360
  • 37
  • 46
3

There is no point in pre-testing. It just introduces a timing window during which the actual status can still change, so you can still be wrong. Just call mkdirs() and test the result it returns. If false, it did nothing; if true, it did something. What exactly it did is really of no actual interest.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • If mkdirs is called when the path already exists, it returns false instead of true. File#mkdirs differs in its behavior from unix `mkdir -p`. So your statement about it having done something is accurate, but does not address the OP's problem of trying to ensure a path exists before using it. – Chris Betti Sep 28 '17 at 12:53
  • @ChrisBetti That's what I said. If you call it, you've ensure that the path exists. – user207421 Sep 28 '17 at 20:26
  • Where you state "Just call mkdirs() and test the result it returns," that part is incorrect. mkdirs() returns false in the following cases: 1) if it could not create the directories. 2) if the directory existed prior to the call. – Chris Betti Sep 30 '17 at 15:53
2

I would create a static method in a utility class which saves a file and automatically creates all necessary directories at the same time. The code inside the utility method may be a bit verbose, but this way, you can keep that ugly, verbose code out of your high-level application logic. And in future projects, you can always reuse the utility. After you split this code off into a utility method, it will also be easy to test in isolation.

I recommend you try to think in terms of building utilities and then using the utilities to build the actual application, rather than mixing detailed, low-level code in everywhere. The utilities you write may be useful on later projects, but that's not the primary goal: even if you only use a utility method on one project, and even if it is only called from one place in the higher-level code, it is still worth it if it helps make the higher-level code clearer. I don't remember which book helped me to get this concept; it may have been The Practice of Programming by Kernighan and Pike, or The Art of UNIX Programming by Raymond, or On Lisp by Graham -- or probably all three. (Of course, it's also important to know your language's standard library, so you don't start writing utilities which are already written for you.)

Alex D
  • 29,755
  • 7
  • 80
  • 126
1

As @stephan mentioned in his answer

Elegance is more of a subjective thing

But since you asked for it

import java.io.File;

public class FileBuilder {
    File file;

    public FileBuilder(String path) {
        file = new File(path);
    }

    public FileBuilder createIfDirDoesNotExists() {
        if (!file.exists()) {
            file.mkdirs();
        }
        return this;
    }

    public File getFile() {
        return file;
    }
}

then you can do

class test {
    public test() {
        File file = new FileBuilder("/tmp/appname/savedir/").createIfDirDoesNotExists().getFile();
    }
}
Community
  • 1
  • 1
Gautam
  • 7,868
  • 12
  • 64
  • 105
0
 File dir = new File(dirPath);
 if(!dir.exists())
     if(!dir.mkdirs()) {//throw or handle exception here.}

You would still need to throw or Handle SecurityException that might be thrown during File.mkdirs()

nitarshs
  • 173
  • 2
  • 10
-1

file.exists() will return whether a directory OR a file exists. You can also use isDirectory() to check if the file path is a directory or not

if (file.isDirectory()){
      //do somethign because this directory already exists
}
else if (file.isFile()){
      //do somethign because this file already exists
}
else {
     boolean created = file.mkdirs();
     if (!created) {
        throw new IOException("Cannot create directory " + file);
     }
}

As to how elegant this is.... I would wrap it in a util method personally to hide some of this extra cruft java makes you write

RNJ
  • 15,272
  • 18
  • 86
  • 131