Skip to content

File 类详解

File 类能做什么?不能做什么?

这个问题困扰过很多 Java 初学者。他们花了半小时终于理解了 File 类的用法,却发现它不能直接读写文件内容。

File 类表示文件或目录的路径,不是文件本身。它能做的:创建、删除、重命名、检查属性。但读写内容,对不起,找 FileInputStream / FileReader。

File 类能做什么 / 不能做什么

能做不能做
检查文件是否存在读写文件内容
获取文件大小打开文件流
创建/删除文件读取文件字节
创建/删除目录写入文件字节
遍历目录搜索文件内容
重命名搜索文件内容

基本用法

创建 File 对象

java
// 方式 1:字符串路径
File f1 = new File("/path/to/file.txt");

// 方式 2:父路径 + 子路径
File f2 = new File("/path/to", "file.txt");

// 方式 3:父 File 对象 + 子路径
File parent = new File("/path/to");
File f3 = new File(parent, "file.txt");

路径分隔符

java
// ❌ 不跨平台
File f = new File("C:\\Users\\test.txt"); // Windows
File f = new File("/home/test.txt");       // Linux/macOS

// ✅ 跨平台
File f = new File("data", "file.txt");
String sep = File.separator; // 根据系统返回 "/" 或 "\\"

判断方法

java
File f = new File("test.txt");
f.exists();           // 是否存在
f.isFile();          // 是否是普通文件
f.isDirectory();      // 是否是目录
f.isAbsolute();       // 是否是绝对路径
f.isHidden();         // 是否是隐藏文件
f.canRead();          // 是否可读
f.canWrite();         // 是否可写
f.canExecute();       // 是否可执行

属性获取

java
File f = new File("test.txt");
f.getName();            // "test.txt"
f.getPath();            // 构造时的路径
f.getAbsolutePath();    // 绝对路径
f.getParent();          // 父目录路径
f.length();             // 文件大小(字节)
f.lastModified();       // 最后修改时间(毫秒时间戳)
new Date(f.lastModified()); // 转换为 Date

CRUD 操作

java
File f = new File("newfile.txt");

// 创建文件
f.createNewFile();      // 不存在才创建,返回 boolean

// 创建目录
File dir = new File("mydir");
dir.mkdir();             // 创建单层目录
dir.mkdirs();            // 创建多层目录

// 删除
f.delete();             // 删除文件或空目录
f.deleteOnExit();        // JVM 退出时删除

// 重命名/移动
f.renameTo(new File("newname.txt")); // 重命名或移动

目录遍历

java
File dir = new File("mydir");

// 列出文件名
String[] names = dir.list();

// 列出 File 对象
File[] files = dir.listFiles();

// 带过滤器
File[] txtFiles = dir.listFiles((d, name) -> name.endsWith(".txt"));

// 按条件过滤
File[] largeFiles = dir.listFiles(f ->
    f.isFile() && f.length() > 1024 * 1024);

文件过滤器

java
// FilenameFilter(按文件名过滤)
File dir = new File("mydir");
String[] files = dir.list((d, name) -> name.endsWith(".java"));

// FileFilter(按文件对象过滤)
File[] dirs = dir.listFiles(File::isDirectory);
File[] largeFiles = dir.listFiles(f -> f.isFile() && f.length() > 0);

递归遍历目录

java
public static void listAllFiles(File dir) {
    if (!dir.isDirectory()) return;
    File[] files = dir.listFiles();
    if (files == null) return;
    for (File f : files) {
        if (f.isDirectory()) {
            listAllFiles(f); // 递归
        } else {
            System.out.println(f.getAbsolutePath());
        }
    }
}

// 统计文件数量
public static long countFiles(File dir) {
    long count = 0;
    if (dir.isDirectory()) {
        File[] files = dir.listFiles();
        if (files != null) {
            for (File f : files) {
                if (f.isDirectory()) {
                    count += countFiles(f);
                } else {
                    count++;
                }
            }
        }
    }
    return count;
}

常见问题

list() / listFiles() 返回 null

java
// ❌ 不检查 null
File[] files = dir.listFiles();
for (File f : files) { // 空目录或权限不足时 null,抛 NPE
}

// ✅ 检查 null
File[] files = dir.listFiles();
if (files != null) {
    for (File f : files) {
        // 处理
    }
}

中文路径名

Java 对中文路径名的支持很好,但有时在不同操作系统之间拷贝时可能出问题。

总结

┌─────────────────────────────────────────────────────────────────┐
│  File 类:文件系统的「指针」,不是文件本身                          │
│                                                                 │
│  能做:检查属性、创建删除、遍历目录                               │
│  不能做:读写内容(找 FileInputStream / Files)                   │
│                                                                 │
│  口诀:File 是路径,读写找流                                      │
└─────────────────────────────────────────────────────────────────┘

基于 VitePress 构建