教程中心 / Java教程 / 文件操作

文件操作

12分钟 I/O流

什么是File类?

File类是Java中用于表示文件或目录路径的类。注意!File类不负责文件的读写操作,它只负责文件/目录的创建、删除、查询等管理工作。真正的数据读写要靠I/O流。

生活比喻

File类就像图书馆的"目录卡片"。卡片告诉你某本书在哪里(路径)、书名叫什么(文件名)、有多少页(文件大小),但书里的内容(数据)需要你去书架上实际翻阅才能看到。卡片只是管理信息,不存储内容。

File类的创建方式

File类有三种构造方式,代表不同的路径含义:

import java.io.File;

public class FileConstructorDemo {
    public static void main(String[] args) {
        // 方式1:绝对路径
        File file1 = new File("C:/users/admin/document.txt");

        // 方式2:相对路径(相对于当前项目目录)
        File file2 = new File("src/main/java/Test.java");

        // 方式3:父路径 + 子路径
        File dir = new File("C:/users/admin");
        File file3 = new File(dir, "document.txt");

        // 方式4:使用System属性获取路径
        String userDir = System.getProperty("user.dir");
        File file4 = new File(userDir, "data.txt");

        System.out.println("绝对路径: " + file1.getAbsolutePath());
        System.out.println("相对路径: " + file2.getPath());
    }
}

File类的常用方法

1. 判断方法

方法返回类型说明
exists()boolean文件/目录是否存在
isFile()boolean是否为普通文件
isDirectory()boolean是否为目录
isAbsolute()boolean路径是否为绝对路径
isHidden()boolean是否为隐藏文件
canRead()boolean是否可读
canWrite()boolean是否可写
canExecute()boolean是否可执行

2. 获取信息方法

方法返回类型说明
getName()String获取文件名(不含路径)
getPath()String获取构造时的路径
getAbsolutePath()String获取绝对路径
getParent()String获取父目录路径
getParentFile()File获取父目录File对象
length()long文件大小(字节)
lastModified()long最后修改时间(时间戳)

3. 创建和删除方法

方法返回类型说明
createNewFile()boolean创建新文件(目录存在时)
mkdir()boolean创建单层目录
mkdirs()boolean创建多层目录
delete()boolean删除文件/目录

4. 目录操作方法

方法返回类型说明
list()String[]列出目录下所有文件名
listFiles()File[]列出目录下所有文件对象
list(FilenameFilter)String[]按过滤器列出
listFiles(FileFilter)File[]按过滤器列出

文件和目录操作示例

创建文件

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

public class CreateFileDemo {
    public static void main(String[] args) {
        String userDir = System.getProperty("user.dir");
        File testFile = new File(userDir, "test.txt");

        try {
            if (!testFile.exists()) {
                boolean created = testFile.createNewFile();
                System.out.println("文件创建成功: " + created);
            } else {
                System.out.println("文件已存在");
            }

            System.out.println("文件名: " + testFile.getName());
            System.out.println("文件路径: " + testFile.getPath());
            System.out.println("绝对路径: " + testFile.getAbsolutePath());
            System.out.println("父目录: " + testFile.getParent());
            System.out.println("文件大小: " + testFile.length() + " bytes");
            System.out.println("最后修改: " + new java.util.Date(testFile.lastModified()));

        } catch (IOException e) {
            System.out.println("创建文件失败: " + e.getMessage());
        }
    }
}

创建目录

import java.io.File;

public class CreateDirectoryDemo {
    public static void main(String[] args) {
        String userDir = System.getProperty("user.dir");

        // 创建单层目录
        File dir1 = new File(userDir, "testdir");
        if (!dir1.exists()) {
            boolean created = dir1.mkdir();
            System.out.println("单层目录创建: " + created);
        }

        // 创建多层目录(包含父目录)
        File dir2 = new File(userDir, "parent/child/grandchild");
        if (!dir2.exists()) {
            boolean created = dir2.mkdirs();
            System.out.println("多层目录创建: " + created);
        }

        // 列出目录内容
        File parent = new File(userDir);
        File[] files = parent.listFiles();
        if (files != null) {
            System.out.println("\n当前目录内容 (" + files.length + " 项):");
            for (File f : files) {
                String type = f.isDirectory() ? "[DIR]" : "[FILE]";
                System.out.println("  " + type + " " + f.getName());
            }
        }
    }
}

遍历目录(带过滤器)

import java.io.File;
import java.io.FilenameFilter;

public class DirectoryFilterDemo {
    public static void main(String[] args) {
        String userDir = System.getProperty("user.dir");
        File dir = new File(userDir);

        // 只显示.java文件
        System.out.println("===== Java文件 =====");
        String[] javaFiles = dir.list((d, name) -> name.endsWith(".java"));
        if (javaFiles != null) {
            for (String f : javaFiles) {
                System.out.println("  " + f);
            }
        }

        // 只显示目录
        System.out.println("\n===== 目录 =====");
        File[] directories = dir.listFiles(File::isDirectory);
        if (directories != null) {
            for (File d : directories) {
                System.out.println("  " + d.getName());
            }
        }
    }
}

路径分隔符注意事项

跨平台问题

Windows使用反斜杠\,Linux/Mac使用正斜杠/。Java程序可能在不同系统运行,请使用File.separator或Paths.get()来构建路径。

// 正确方式
File file1 = new File("parent" + File.separator + "child");
File file2 = new File("parent/child");  // Java也接受正斜杠

// Java 7+ 推荐使用Paths
import java.nio.file.Paths;
File file3 = Paths.get("parent", "child").toFile();

// 获取系统相关分隔符
System.out.println("路径分隔符: " + File.separator);
System.out.println("文件分隔符: " + File.pathSeparator);  // 用于PATH类环境变量

删除文件和目录

import java.io.File;

public class DeleteDemo {
    public static void main(String[] args) {
        String userDir = System.getProperty("user.dir");

        // 删除文件
        File file = new File(userDir, "toDelete.txt");
        if (file.exists()) {
            boolean deleted = file.delete();
            System.out.println("文件删除: " + deleted);
        }

        // 注意:delete()删除目录时,目录必须为空
        // 要删除非空目录,需要递归删除所有内容
    }
}

常见错误和注意事项

错误1:混淆File和I/O

File类只是路径表示,创建文件只是创建了一个"卡片",真正写入内容需要使用FileOutputStream等I/O类。

错误2:delete()无法删除非空目录

如果要删除包含文件的目录,必须先删除所有文件,或者自己实现递归删除。

提示:Java 7+推荐使用NIO.2

Java 7引入了java.nio.file包,提供了更现代的文件操作API,包括Files类和Path接口。建议新代码优先使用NIO.2。

小结

  • File类只管理文件/目录的元信息,不负责读写数据
  • createNewFile()创建新文件,mkdir()创建目录
  • delete()删除文件,但无法删除非空目录
  • listFiles()可以列出目录下的所有文件和子目录
  • 跨平台开发时使用File.separator构建路径
☕ Java 在线代码编辑器
📝 运行结果