Skip to content
Java file handling 5 min read

Create a File

Creating a file in Java is one of the first things you learn when working with the filesystem. Java gives you several ways to do it — from the classic java.io.File API to the modern java.nio.file.Files utility introduced in Java 7. Each approach has its own strengths, so it is worth knowing all of them.

Using File.createNewFile()

The simplest and most widely known approach uses java.io.File. The createNewFile() method atomically creates a new, empty file only if the file does not already exist. It returns true when the file was created and false when it already existed.

import java.io.File;
import java.io.IOException;

public class CreateFileExample {
    public static void main(String[] args) {
        File file = new File("notes.txt");
        try {
            boolean created = file.createNewFile();
            if (created) {
                System.out.println("File created: " + file.getAbsolutePath());
            } else {
                System.out.println("File already exists.");
            }
        } catch (IOException e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}

Output (first run):

File created: /home/user/projects/notes.txt

Output (second run):

File already exists.

Note: createNewFile() throws IOException if the parent directory does not exist. Always ensure the directory tree is in place before calling it (see the section on nested directories below).

Creating a File in a Specific Directory

Pass the full path — either absolute or relative — to the File constructor:

import java.io.File;
import java.io.IOException;

public class FileInDirectory {
    public static void main(String[] args) throws IOException {
        // Relative path: creates "data/config.txt" under the working directory
        File file = new File("data/config.txt");

        // Create the parent directory if it does not exist
        file.getParentFile().mkdirs();

        if (file.createNewFile()) {
            System.out.println("Created: " + file.getAbsolutePath());
        }
    }
}

mkdirs() creates the entire chain of missing parent directories in one call (unlike mkdir(), which only creates one level).


Using FileOutputStream

Opening a FileOutputStream on a non-existent path creates the file as a side effect. This is useful when you want to create the file and write to it in the same step.

import java.io.FileOutputStream;
import java.io.IOException;

public class CreateWithStream {
    public static void main(String[] args) {
        try (FileOutputStream fos = new FileOutputStream("output.txt")) {
            fos.write("Hello, Java!".getBytes());
            System.out.println("File created and written.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Output:

File created and written.

Warning: If output.txt already exists, FileOutputStream will overwrite it (truncate to zero bytes) by default. Use new FileOutputStream("output.txt", true) to append instead.


Using NIO Files.createFile() (Java 7+)

The java.nio.file.Files class offers Files.createFile(), which is the modern, preferred approach. It throws FileAlreadyExistsException when the file is already there — a checked exception that makes the conflict explicit rather than returning a silent boolean.

import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class NioCreateFile {
    public static void main(String[] args) {
        Path path = Paths.get("report.txt");
        try {
            Files.createFile(path);
            System.out.println("File created: " + path.toAbsolutePath());
        } catch (FileAlreadyExistsException e) {
            System.out.println("File already exists: " + e.getFile());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Output (first run):

File created: /home/user/projects/report.txt

Tip: In Java 11+ you can use Path.of("report.txt") instead of Paths.get(...) — it is shorter and reads more naturally.

Creating Directories Alongside the File

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class NioCreateWithDirs {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("logs/2026/app.log");
        Files.createDirectories(path.getParent()); // creates logs/2026/
        Files.createFile(path);
        System.out.println("Created: " + path.toAbsolutePath());
    }
}

Using FileWriter

FileWriter is another shortcut that creates a file when you open it — handy for text content:

import java.io.FileWriter;
import java.io.IOException;

public class CreateWithWriter {
    public static void main(String[] args) {
        try (FileWriter fw = new FileWriter("greeting.txt")) {
            fw.write("Hello from FileWriter!");
            System.out.println("File created.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Like FileOutputStream, FileWriter will truncate any existing file. Use new FileWriter("greeting.txt", true) for append mode.


Comparing the Approaches

MethodCreates Empty FileWrites ImmediatelyOverwrites ExistingAvailable Since
File.createNewFile()YesNoNo (returns false)Java 1.2
FileOutputStreamYesYesYes (truncates)Java 1.0
Files.createFile()YesNoNo (throws exception)Java 7
FileWriterYesYesYes (truncates)Java 1.1

For new code, prefer Files.createFile() from NIO.2 — it is explicit, gives you better exception information, and integrates cleanly with Path.


Checking Before Creating

Always think about what should happen if the file already exists. A common defensive pattern:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class SafeCreate {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("config.properties");

        if (Files.notExists(path)) {
            Files.createFile(path);
            System.out.println("New config file created.");
        } else {
            System.out.println("Config file already present — skipping.");
        }
    }
}

Note: Between the notExists() check and the createFile() call there is a tiny race window where another process could create the same file. If you need strict atomicity in a concurrent environment, rely on the FileAlreadyExistsException thrown by Files.createFile() rather than the pre-check.


Under the Hood

When you call File.createNewFile() or Files.createFile(), the JVM delegates to a native OS call — on Linux this is open(path, O_CREAT | O_EXCL, 0666). The O_EXCL flag makes creation atomic at the filesystem level: if two threads race to create the same file, exactly one wins and the other gets an error. That is why Files.createFile() throwing FileAlreadyExistsException is actually safer than checking existence first — you get the OS atomicity guarantee for free.

FileOutputStream and FileWriter, on the other hand, use open(path, O_CREAT | O_WRONLY | O_TRUNC) — the O_TRUNC flag says “truncate if it exists”, which is why they silently overwrite.

File metadata (timestamps, permissions) is written to the filesystem’s inode at creation time. On most systems the default permissions come from the process’s umask, but with Files.createFile() you can pass FileAttribute objects to set permissions explicitly:

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.util.Set;

public class CreateWithPermissions {
    public static void main(String[] args) throws IOException {
        Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-r--r--");
        FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);
        Path path = Paths.get("secure.txt");
        Files.createFile(path, attr);
        System.out.println("File created with 644 permissions.");
    }
}

Note: PosixFilePermission is only available on POSIX-compatible operating systems (Linux, macOS). On Windows, use AclFileAttributeView instead.


Last updated June 13, 2026
Was this helpful?