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()throwsIOExceptionif 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.txtalready exists,FileOutputStreamwill overwrite it (truncate to zero bytes) by default. Usenew 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 ofPaths.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
| Method | Creates Empty File | Writes Immediately | Overwrites Existing | Available Since |
|---|---|---|---|---|
File.createNewFile() | Yes | No | No (returns false) | Java 1.2 |
FileOutputStream | Yes | Yes | Yes (truncates) | Java 1.0 |
Files.createFile() | Yes | No | No (throws exception) | Java 7 |
FileWriter | Yes | Yes | Yes (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 thecreateFile()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 theFileAlreadyExistsExceptionthrown byFiles.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:
PosixFilePermissionis only available on POSIX-compatible operating systems (Linux, macOS). On Windows, useAclFileAttributeViewinstead.
Related Topics
- File Class — understand the
Fileobject that underpins classic file operations - Write to a File — next step after creating a file: writing content into it
- Read a File Line by Line — efficiently reading text from a file you created
- Delete a File — how to cleanly remove files with
File.delete()andFiles.delete() - NIO.2: Path & Files — the modern NIO.2 API for all filesystem operations
- FileOutputStream — low-level byte-stream writing when you need full control