在Java中File类如何操作文件和目录_Java文件基础API解析

File对象创建后不等于文件已存在,仅是路径抽象;exists()、createNewFile()等方法才触发磁盘操作;delete()等操作失败返回false而非异常,需检查返回值。

File对象创建后不等于文件已存在

很多人以为 new File("path/to/file.txt") 就创建了文件,其实只是构造了一个路径抽象。它既不检查路径是否存在,也不触发任何磁盘操作。只有调用 exists()createNewFile()mkdirs() 等方法时,才真正与文件系统交互。

常见错误:直接对未存在的 File 对象调用 delete()renameTo(),结果静默失败(返回 false),却不检查返回值。

  • 务必在关键操作后检查返回值:i

    f (!file.delete()) { /* 处理失败 */ }
  • createNewFile() 仅当文件不存在时才创建并返回 true;若已存在或父目录不存在,返回 false
  • 路径中含中文或空格时,确保使用 UTF-8 编码构建字符串,否则在某些平台(如旧版 Windows)可能解析异常

mkdir() 和 mkdirs() 的区别直接影响目录创建成败

mkdir() 只创建最后一级目录,要求其父目录必须已存在;mkdirs() 会逐级创建所有缺失的上级目录。这是新手最常踩的坑——用 mkdir() 创建 "a/b/c" 却没提前建好 "a""a/b",结果返回 false

典型场景:保存日志到 "logs/2025/06/15/app.log",必须用 new File("logs/2025/06/15").mkdirs(),否则写入会因目录不存在而抛 FileNotFoundException

  • mkdir() 返回 false 不一定代表权限问题,更可能是父目录缺失
  • mkdirs() 在多线程环境下不是原子操作,可能有竞态(比如两个线程同时创建同一路径),需自行加锁或捕获 SecurityException
  • Linux/macOS *意 umask 影响实际权限,Java 不控制新建目录的权限位

listFiles() 返回 null 而不是空数组的三种情况

listFiles() 在以下任一情况下返回 null:路径不存在、不是目录、没有读取权限。它**从不返回空数组**来表示“目录为空”,这点和 list() 不同(后者目录为空时返回长度为 0 的字符串数组)。

因此,不判空直接遍历 listFiles() 结果,极易触发 NullPointerException

  • 安全写法:
    File[] files = dir.listFiles();
    if (files != null) {
        for (File f : files) { /* 安全遍历 */ }
    }
  • 想获取文件名列表(不含路径),优先用 list();需要完整 File 对象再用 listFiles()
  • 递归遍历时,listFiles() 对符号链接的处理依赖底层 OS,Linux 默认跟随,Windows 可能不跟随,行为不一致

File 类已被 Path / Files 替代,但仍有不可替代的场景

Java 7 引入的 java.nio.file.Pathjava.nio.file.Files 是现代首选,支持符号链接、原子移动、访问控制列表等。但 File 并未被废弃,仍在一些地方必须使用:

  • Swing/AWT 文件对话框(JFileChooser.getSelectedFile() 返回 File
  • Servlet 中 getRealPath() 返回 String,通常要转成 File 再判断是否存在
  • 某些老框架(如早期 Spring Resource)仍以 File 为参数类型

混合使用时注意:不要把 File.toPath() 得到的 Path 和原始 File 混用同一个物理路径做并发操作,因为 File 的部分方法(如 lastModified())可能缓存状态,而 Files 方法总是实时读取。