📝 一句话概括
IO 章开门第一课:先认识"文件"本身,再学搬运数据。File 类是文件和文件夹的"路标"——注意,new File 只是造路标,不是造文件。学完这节,你就能用代码查文件、建文件夹、扫目录。
1. 引入:为什么要学 IO
前面写的程序数据都住在内存里——程序一关,全没了。想让数据"住得久"(保存账号、存日志、读配置),就得落到硬盘上:往文件里写、从文件里读——这就是 I/O(Input/Output,输入/输出)。
但搬数据之前,先得能找到并描述文件。Java 用 java.io.File 类干这件事:
- 文件(a.txt)→ File 对象
- 文件夹(目录)→ 也是 File 对象——一个类,两用
2. 创建 File 对象:三种写法
File f1 = new File("D:\\test\\a.txt"); // 写全路径
File f2 = new File("D:\\test", "a.txt"); // 父路径 + 子路径(字符串拆开)
File f3 = new File(dir, "a.txt"); // 父路径用 File 对象装
三个要点:
new File≠ 创建文件——它只是在内存里造了个"路标"。磁盘上有没有这个文件,new的时候一概不管、也不报错。想真建文件得调createNewFile()。- 绝对路径 vs 相对路径:
D:\test\a.txt从盘符写起是绝对路径;a.txt、./a.txt从项目目录找起是相对路径——换台电脑跑,绝对路径可能就失效了,练习时相对路径更稳。 - 路径分隔符:Windows 是
\,但\在字符串里是转义符,得写\\;偷懒写/也行(Java 帮你兼容)。
📝 类比 9.1
这套路是不是很熟?File 对象就像 Class 对象的远房亲戚——都是"抽象表示":Class 对象是类的说明书,File 对象是文件的路标。真正的"活儿"(读写数据/操作字节)都要靠后面的 IO 流来干。
3. File 常用方法:四大族
判断族
f.exists() // 路标指向的文件/文件夹真的存在吗?
f.isFile() // 是文件吗?
f.isDirectory() // 是文件夹吗?
获取族
f.getName() // a.txt(文件名)
f.getAbsolutePath() // D:\test\a.txt(绝对路径)
f.length() // 字节数(注意:文件夹的 length 无意义,返回 0 或垃圾值)
f.lastModified() // 最后修改时间(毫秒值 → 6.6 的 Date 能接住)
创建/删除族
f.createNewFile() // 真建文件!已存在返回 false;抛受检 IOException
f.mkdirs() // 真建文件夹!多级一起建(a/b/c 一条龙),mkdir() 只建一级
f.delete() // 直接删除,不进回收站!文件夹必须为空才能删
遍历族(本节重头戏)
String[] names = dir.list(); // 只给名字(字符串数组)
File[] files = dir.listFiles(); // 给 File 对象数组——能接着调方法,实用
File[] txts = dir.listFiles(过滤器); // 想挑着拿?传过滤器
过滤器是函数式接口 FileFilter(只有一个 accept(File f) 方法)——4.7 的 Lambda 直接上岗:
File[] txts = dir.listFiles(f -> f.getName().endsWith(".txt") && f.isFile());
4. 收网旧账
- 4.7 函数式编程:
listFiles(FileFilter)的参数是函数式接口——Lambda 三段式、省略规则全套实战。 - 7.8 Stream:
File[]到手可以Arrays.stream(files).filter(...).forEach(...)一路丝滑。 - 5.2 受检异常:
createNewFile()抛IOException——"跟外部世界打交道必受检"的又一实锤(和ClassNotFoundException一队)。 - 6.6 日期类:
lastModified()返回毫秒值,new Date(millis)+ 格式化就能显示成"2026-09-19 16:43"。 - 9.1 三把钥匙:
对象.getClass()的对象思维——路标类抽象表示真实物的又一例。
5. 动手:Demo05 给文件做个体检 + 扫目录
import java.io.File;
import java.io.IOException;
public class Demo05 {
public static void main(String[] args) throws IOException {
// 一、体检一个文件
File f = new File("test\\a.txt");
System.out.println("存在吗:" + f.exists());
System.out.println("绝对路径:" + f.getAbsolutePath());
if (!f.exists()) {
System.out.println("创建成功吗:" + f.createNewFile()); // 真建文件
}
System.out.println("是文件吗:" + f.isFile() + ",大小:" + f.length());
// 二、建个多级文件夹
File dir = new File("test\\demo\\src");
System.out.println("建文件夹:" + dir.mkdirs());
// 三、扫目录:只挑 .txt(Lambda 过滤器)
File[] files = new File("test").listFiles(fd -> fd.getName().endsWith(".txt"));
for (File file : files) {
System.out.println(file.getName() + " → " + file.length() + " 字节");
}
}
}
三个 30 秒实验:
- 把
new File("test\\a.txt")改成new File("test/a.txt")再跑——照常成功:/也能当分隔符。 - 对
a.txt(文件,不是文件夹)调listFiles()——返回null,接着.length直接 NPE。亲手踩一遍坑。 - 给
a.txt调delete()后去 D 盘翻回收站——没有!它被直接删了(所以 delete 前先exists()三思)。
6. 常见误区
⚠️ 五个坑
- ❌ 以为
new File会创建文件 —— 只是造路标。不调createNewFile()磁盘上啥也没有。 - ❌
delete()期待走回收站 —— 直接送走,找不回来!删重要东西前先确认路径(这也是我们删文件永远先备份的原因)。 - ❌ 对不存在的路径 / 文件路径调
listFiles()—— 返回null,接一个for循环直接 NPE。先exists()+isDirectory()再遍历。 - ❌
mkdir()想一级建多级 ——a/b/c中间哪级不存在就失败返回 false;用mkdirs()一条龙。 - ❌ 对文件夹调
length()—— 文件夹没有"大小"这个概念,结果不可信;要算大小得遍历里面所有文件累加(后面的递归活儿)。
7. 可折叠自测
❓ Q1:`new File("D:\\test\\a.txt")` 执行后,磁盘上有了 a.txt 吗?
没有!只是内存里多了个路标对象。磁盘有没有这个文件与它无关,用 exists() 查,用 createNewFile() 才真建。
❓ Q2:`File` 既表示文件又表示文件夹,用什么方法区分它指向的是哪一种?
isFile() / isDirectory()。另外 exists() 永远是第一步——路标可能指向空地。
❓ Q3:`mkdir()` 和 `mkdirs()` 的区别?建 `a/b/c` 三级该用哪个?
mkdir() 只建最后一级且父目录必须已存在;mkdirs() 把缺的父目录全建齐。建多级用 mkdirs()。
❓ Q4:`list()` 和 `listFiles()` 返回类型差在哪?实战选哪个?
list() 返回 String[](只有名字);listFiles() 返回 File[](每个元素还能继续调方法)。实战基本都用 listFiles()。
❓ Q5(毕业题):不看笔记,用一行 Lambda 过滤器 + 遍历,打印某目录下所有 `.md` 文件的名字和字节数,并在开头判断"该目录存在且真是文件夹"。
File dir = new File("笔记目录");
if (dir.exists() && dir.isDirectory()) {
File[] mds = dir.listFiles(f -> f.isFile() && f.getName().endsWith(".md"));
for (File f : mds) System.out.println(f.getName() + " → " + f.length() + " 字节");
}
写出来,你已经能用代码"逛文件夹"了——下节开始往文件里装数据。
8. 下一步学什么
- ☑ 10.2 字节流 ✅ —— 点此复习:FileOutputStream 三保命规矩(自动建/默认清空/close)、read 的 -1 哨兵、byte[] 小推车、复制图片实战。
相关笔记
- 第九章 反射机制和注解/9.1 反射概述:Class 对象是类的说明书,File 对象是文件的路标——抽象表示一家亲
- 第四章 面向对象(下)/4.7 函数式编程:
listFiles(FileFilter)就是函数式接口 + Lambda 的实战主场 - 第五章 异常/5.2 运行时异常与编译时异常:
createNewFile()的IOException—— 外部世界必受检 - 第六章 Java API/6.6 日期和时间类:
lastModified()的毫秒值交给 Date 和格式化类翻译 - 第七章 集合/7.8 Stream(流):
File[]接上 Stream,过滤遍历一气呵成 - 第一章 Java开发入门/1.4 Java程序的运行机制:内存是"临时工位",硬盘才是"仓库"——IO 的存在理由