Files.createDirectories()

Create a directory and any missing parents in one call that is safe to repeat, and see how it differs from createDirectory.

Signature
public static Path createDirectories(Path dir, FileAttribute<?>... attrs) throws IOException
  • Added in Java Java 7

Parameters

ParameterTypeDescription
$dirPathThe directory to create, along with any missing parent directories.
$attrsoptionalFileAttribute<?>...Attributes to set atomically on each directory created, such as POSIX permissions from PosixFilePermissions.asFileAttribute. Directories that already exist are not changed.

Return value

PathThe directory path that was passed in.

Errors

FileAlreadyExistsException if dir exists but is not a directory; IOException for other failures, such as a parent path that is a regular file or a lack of permission; UnsupportedOperationException if an attribute cannot be set on creation.

Files.createDirectories(dir) creates the directory and every missing parent, the NIO version of mkdir -p. If the directory already exists, it does nothing and returns normally. That makes it safe to call every time before you write, without checking first.

createDirectory is stricter

SituationcreateDirectorycreateDirectories
Parent missingNoSuchFileExceptioncreates parents
Directory already thereFileAlreadyExistsExceptionno error
A file has that nameFileAlreadyExistsExceptionFileAlreadyExistsException

Use createDirectory when an existing directory means something is wrong, for example a per-job working directory that must start empty. Use createDirectories for storage layouts such as uploads/2026/10/13, where several requests may race to create the same folder; whichever one loses still succeeds.

Compared with java.io.File.mkdirs

The old File.mkdirs() returns false on failure with no reason, and also returns false when the directory already exists. createDirectories throws an exception that names the problem, which is what you want in a server log.

Permissions

New directories get the default permissions of the process, shaped by its umask. To create a private directory for secrets or temporary user data on Linux, pass POSIX permissions as an attribute so they are set at creation, with no window where the directory is readable by others:

FileAttribute<Set<PosixFilePermission>> owner =
        PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------"));
Files.createDirectories(dir, owner);

This throws UnsupportedOperationException on file systems without POSIX attributes, such as Windows.

Common mistakes

Passing the file path instead of its parent: createDirectories(path) where path is report.csv makes a directory called report.csv, and the following write fails. Use path.getParent(). Also remember that getParent() returns null for a bare file name such as Path.of("report.csv"), so resolve such names against a configured base directory first.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Create a dated folder such as uploads/2026/10/13 before saving a user's file, safely from many concurrent requests.
  • Make sure a reports or export directory exists at startup so the first nightly job does not fail.
  • Create an owner-only working directory for decrypted files or keys on a shared Linux host.

Frequently asked questions

How do I create a directory if it does not exist in Java?

Call Files.createDirectories(path). It creates any missing parents and does nothing if the directory is already there, so no existence check is needed.

What is the difference between createDirectory and createDirectories?

createDirectory creates one directory and throws if its parent is missing or if it already exists. createDirectories creates all missing parents and succeeds when the directory already exists.

Why does createDirectories throw FileAlreadyExistsException?

A regular file, or something else that is not a directory, already has that name. An existing directory never causes this exception.

More examples

createDirectory versus createDirectories

createDirectory creates exactly one level and treats an existing directory as an error. createDirectories is idempotent, so it is the one to call before writing into a path that may or may not exist yet.

Example · java
void main() throws IOException {
    Path root = Files.createTempDirectory("jobs");
    Path nested = root.resolve("job-7").resolve("work");
    try {
        try {
            Files.createDirectory(nested);
        } catch (NoSuchFileException e) {
            IO.println("createDirectory: parent missing");
        }

        Files.createDirectories(nested);
        try {
            Files.createDirectory(nested);
        } catch (FileAlreadyExistsException e) {
            IO.println("createDirectory: already exists");
        }
        Files.createDirectories(nested);
        IO.println("createDirectories: fine both times");
    } finally {
        Files.deleteIfExists(nested);
        Files.deleteIfExists(nested.getParent());
        Files.deleteIfExists(root);
    }
}

// Output:
// createDirectory: parent missing
// createDirectory: already exists
// createDirectories: fine both times

A file where a directory should be

An existing regular file with the requested name is reported as FileAlreadyExistsException. A regular file part-way along the path fails with a general FileSystemException ("Not a directory" on Linux), so catch IOException if you want to handle both.

Example · java
void main() throws IOException {
    Path root = Files.createTempDirectory("cache");
    Path blocker = root.resolve("thumbnails");
    try {
        Files.writeString(blocker, "not a directory");
        try {
            Files.createDirectories(blocker);
        } catch (FileAlreadyExistsException e) {
            IO.println("in the way: " + Path.of(e.getFile()).getFileName());
        }
        try {
            Files.createDirectories(blocker.resolve("small"));
        } catch (IOException e) {
            IO.println("below a file: " + e.getClass().getSimpleName());
        }
    } finally {
        Files.deleteIfExists(blocker);
        Files.deleteIfExists(root);
    }
}

// Output:
// in the way: thumbnails
// below a file: FileSystemException

A private directory on Linux

The permissions are applied as each directory is created, so there is no moment where other users on the host could list its contents. Attributes apply only to directories this call creates: if secrets already exists with wider permissions, they are left unchanged, so check them when the directory may predate the service.

Example · java
void main() throws IOException {
    Path root = Files.createTempDirectory("svc");
    Path keys = root.resolve("secrets").resolve("keys");
    try {
        var ownerOnly = PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------"));
        Files.createDirectories(keys, ownerOnly);

        Set<PosixFilePermission> perms = Files.getPosixFilePermissions(keys);
        IO.println("keys: " + PosixFilePermissions.toString(perms));
    } finally {
        Files.deleteIfExists(keys);
        Files.deleteIfExists(keys.getParent());
        Files.deleteIfExists(root);
    }
}

// Output:
// keys: rwx------

Discussion

  • Be the first to comment on this lesson.