HOWTO · Java

在 Java 中创建目录

本教程讨论如何在 Java 中创建目录

本页内容

目录是文件系统中用于存储文件的编目结构,创建目录是 Java 中一项常见的文件处理任务。JDK 为此提供了两套 API——传统的 java.io.File 方法和较新的 java.nio.file.Files 辅助方法——而 Apache Commons IO 又提供了第三种选择。本教程将逐一介绍这些方法,以及在选择时真正重要的行为差异。

选择 Java 目录创建方法

对于大多数新代码,优先使用 java.nio.file.Files。当某些父目录可能尚不存在时,调用 Files.createDirectories(path):它一次调用就能创建完整路径,并且不会仅仅因为目录已经存在而失败。如果希望已存在的目标被视为失败,则改用 Files.createDirectory(path)。较早的 File.mkdir() 和 File.mkdirs() 方法只通过一个 boolean 报告成功与否,很容易被忽略;而 Files 方法抛出的受检异常能指明具体问题。FileUtils.forceMkdir() 只有在代码库已经依赖 Apache Commons IO 时才是合理的选择。

各方法之间的重要区别在于如何处理缺失的父目录和已存在的目标:

方法 缺失的父目录 已存在的目标目录 失败信号
File.mkdir() 失败,返回 false 返回 false boolean 返回值
File.mkdirs() 创建它们 返回 false boolean 返回值
Files.createDirectory() NoSuchFileException FileAlreadyExistsException 受检 IOException 子类型
Files.createDirectories() 创建它们 正常返回 受检 IOException 子类型
FileUtils.forceMkdir() 创建它们 正常返回 IOException

使用 File.mkdir() 创建单个目录

File.mkdir() 在 File 实例所持有的路径上恰好创建一个目录。只有当它真正创建了目录时才返回 true;当该名称已被占用、父目录不存在或操作系统拒绝请求时返回 false,因此一定要检查返回值,而不是想当然地认为成功。

下面的程序在工作目录中创建一个名为 reports 的目录,并打印结果:

本节中的代码以及显示的标签或输出仍为英文。

import java.io.File;

public class MkdirExample {
    public static void main(String[] args) {
        File dir = new File("reports");
        boolean created = dir.mkdir();
        System.out.println("mkdir() returned: " + created);
        System.out.println("Directory exists: " + dir.isDirectory());
    }
}
mkdir() returned: true
Directory exists: true

false 结果不会告诉你任何原因——如果目录预先存在也可以接受,可以在事后检查 dir.isDirectory();或者改用 Files.createDirectory() 以获得类型化的失败信息。当安全管理器拒绝写访问时,mkdir() 还可能抛出非受检的 SecurityException。

使用 File.mkdirs() 创建目录树

File.mkdirs() 在一次调用中创建目标目录以及路径上所有缺失的父目录:

本节中的代码以及显示的标签或输出仍为英文。

import java.io.File;

public class MkdirsExample {
    public static void main(String[] args) {
        File dir = new File("reports/2026/october");
        boolean created = dir.mkdirs();
        System.out.println("mkdirs() returned: " + created);
        System.out.println("Directory exists: " + dir.isDirectory());
    }
}
mkdirs() returned: true
Directory exists: true

注意,只有当 mkdirs() 创建了该目录连同所有必需的父目录时才返回 true。在已存在的目录树上运行它会返回 false,尽管并没有出任何问题,而且 false 结果也不会说明是哪一级失败了。当“成功”仅仅意味着目录已经存在时,请用 isDirectory() 来验证。

使用 Files.createDirectory() 创建单个目录

Files.createDirectory(path) 是 mkdir() 的 NIO 等价物:它恰好创建一个目录,并在父目录缺失时失败。由于它的失败都是受检异常,编译器会强制你处理它们,而且异常类型本身就指明了问题——名称被占用时抛出 FileAlreadyExistsException,父目录缺失时抛出 NoSuchFileException。

本节中的代码以及显示的标签或输出仍为英文。

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 CreateDirectoryExample {
    public static void main(String[] args) {
        Path path = Paths.get("logs");
        try {
            Files.createDirectory(path);
            System.out.println("Created directory: " + path);
        } catch (FileAlreadyExistsException e) {
            System.out.println("Already exists: " + path);
        } catch (IOException e) {
            System.out.println("Could not create directory: " + e);
        }
    }
}
Created directory: logs

单独捕获 FileAlreadyExistsException 可以让常见的“已经存在”情况保持安静,而其他 IOException 子类型仍会作为失败暴露出来。

使用 Files.createDirectories() 创建目录树

Files.createDirectories(path) 在一次调用中创建目标目录和所有缺失的父目录;与 mkdirs() 不同的是,当目录已经存在时它会正常返回——当你只是需要该路径存在时,这是推荐调用。当一个常规文件占据该路径时它仍会抛出 FileAlreadyExistsException,并在权限被拒绝等真实失败情况下抛出其他 IOException 子类型。

本节中的代码以及显示的标签或输出仍为英文。

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

public class CreateDirectoriesExample {
    public static void main(String[] args) {
        Path path = Paths.get("data/archive/2026");
        try {
            Files.createDirectories(path);
            System.out.println("Directory ready: " + path);
        } catch (IOException e) {
            System.out.println("Could not create directory: " + e);
        }
    }
}
Directory ready: data/archive/2026

使用 Apache Commons IO 的 FileUtils.forceMkdir()

FileUtils.forceMkdir() 不属于 JDK;它位于 Apache Commons IO 中,因此项目需要 commons-io 依赖(例如 Maven 或 Gradle 中的 commons-io:commons-io 构件)。由于该库不在标准类路径上,这里以内联方式展示该调用,而不是给出一个可运行的示例:

FileUtils.forceMkdir(new File("data/archive/2026"));

与 createDirectories() 一样,它会创建目录及所有缺失的父目录,并在目录已存在时静默返回——尽管名字如此,“force”指的是创建所需的父目录,而不是覆盖任何东西。当一个非目录文件占据该路径或目录无法创建时,它会抛出 IOException。除非代码库已经使用 Commons IO,否则请优先使用标准的 Files 方法。