31

I'm creating a simple program that will try to read in "conf/conf.xml" from disk, but if this file or dir doesn't exist will instead create them.

I can do this using the following code:

    // create subdirectory path
    Path confDir = Paths.get("./conf"); 

    // create file-in-subdirectory path
    Path confFile = Paths.get("./conf/conf.xml"); 

    // if the sub-directory doesn't exist then create it
    if (Files.notExists(confDir)) { 
        try { Files.createDirectory(confDir); }
        catch (Exception e ) { e.printStackTrace(); }
    }

    // if the file doesn't exist then create it
    if (Files.notExists(confFile)) {
        try { Files.createFile(confFile); }
        catch (Exception e ) { e.printStackTrace(); }
    }

My questions is if this really the most elegant way to do this? It seems superflous to need to create two Paths simple to create a new file in a new subdirectory.

user3341332
  • 399
  • 1
  • 3
  • 10
  • 3
    `Path` has `.resolve()` and `.getParent()`, so you could start there – fge Feb 22 '14 at 17:57
  • I don't get your exception logic: Why do you try to create the file if the directory does not exist and can't be created? – steffen Feb 22 '14 at 18:00

3 Answers3

29

You could declare your confFile as File instead of Path. Then you can use confFile.getParentFile().mkdirs();, see example below:

// ...

File confFile = new File("./conf/conf.xml"); 
confFile.getParentFile().mkdirs();

// ...

Or, using your code as is, you can use:

Files.createDirectories(confFile.getParent());
Marko Gresak
  • 7,950
  • 5
  • 40
  • 46
  • Wouldn't using mkdirs() or createDirectories(..) trip an exception if .conf/ already existed?I can see how it could be done with File, but wondered why the Paths/Files under nio didn't have an equally simply way to do this. – user3341332 Feb 22 '14 at 18:07
  • @user3341332 No. It doesn't throw exceptions at all. See the Javadoc. – user207421 Feb 22 '14 at 18:27
  • 4
    But note that `Path.getParent()` return `null` if there is no more parts in the "string" of the Path. For example a `Path` with `dir/b.txt` will return path `dir` but `dir.getParent()` will return `null`. So `Files.createDirectories(dir.getParent());` throw a `NullPointerException` although `dir`is inside other directory. – PhoneixS Apr 29 '15 at 15:34
  • 9
    why go back to java.io.File when you're starting with java.nio.Path? – Adam Sep 15 '17 at 11:34
  • 2
    https://stackoverflow.com/questions/27069447/nio-getparentfile-mkdir#answer-27069848 – Adam Sep 15 '17 at 11:37
4

You can create directory and file in one code line:

Files.createFile(Files.createDirectories(confDir).resolve(confFile.getFileName()))

Files.createDirectories(confDir) will not throw an exception if the folder already exists and returns Path in any case.

Valeriy K.
  • 2,616
  • 1
  • 30
  • 53
  • `Files.createDirectories(confDir)` will throw a `FileAlreadyExistsException`, if the directory already exists. – mks-d Jan 27 '21 at 19:37
  • @mks-d I verified - run the code 2 times and don't get the exception. Which java version you use? – Valeriy K. Jan 28 '21 at 13:44
  • @ValeriyK. good point. And my bad since it was with `createDirectory​(Path)` and not `createDirectories(Path)`. The version was ancient, Java 8. – mks-d Feb 02 '21 at 08:44
0

You could do the following:

// Get your Path from the string
Path confFile = Paths.get("./conf/conf.xml"); 
// Get the portion of path that represtents directory structure.  
Path subpath = confFile.subpath(0, confFile.getNameCount() - 1);
// Create all directories recursively
/**
     * Creates a directory by creating all nonexistent parent directories first.
     * Unlike the {@link #createDirectory createDirectory} method, an exception
     * is not thrown if the directory could not be created because it already
     * exists.
     *
*/
Files.createDirectories(subpath.toAbsolutePath()))