1. 底层硬件:硬盘
硬盘是持久化 I/O 硬件设备,分为机械硬盘 HDD、固态硬盘 SSD。 硬盘硬件层面由大量扇区组成,扇区是硬件最小读写单元(常见 512B/4KB)。硬盘本身只是一堆扁平的二进制块,硬件上没有 "文件、文件名、文件夹" 这些概念 。操作系统需要一套软件规则,把磁盘上原始扇区组织成我们使用的文件,这套规则就是文件系统 。
2. 文件系统核心概念
2.1 文件:数据 + 元信息
文件分为两部分:
- 文件内容(数据):真正保存业务数据。
- 元信息(元数据 metadata):不属于文件内容,描述文件属性:文件名、大小、修改时间、权限、类型等。
硬盘会分别存储文件数据内容和文件元信息。
注意:目录(文件夹)本身也是一种特殊文件,目录文件内部保存的就是一批文件的元信息映射关系,用来管理下属文件 / 子目录。

2.2 树形目录结构
文件数量变多之后,文件系统使用树形结构组织全部文件。根节点出发不断分支,节点可以是普通文件,也可以是目录。
- Windows:多棵树,每个磁盘分区一个根,例如C:\;
- Linux:单根树,只有一个根/,磁盘分区通过挂载接入这颗大树。
目录的作用就是管理子节点,让大量文件逻辑清晰、方便用户定位使用。

2.3 文件路径
径用来在树形文件树上唯一定位一个文件,分为两种:
- 绝对路径 :从根节点开始完整描述路径。Windows 示例:C:\Program Files\test.txt;Linux:/home/user/test.txt。
- 相对路径 :从当前工作目录 出发定位文件;.代表当前目录,..代表父目录。
不同系统路径分隔符不一样:Windows 使用\,Linux 使用/,Java File类提供pathSeparator自动适配系统分隔符。

2.4 文件类型、权限、链接
1.文本文件 vs 二进制文件
- 文本文件: 内容是经过字符集编码的字符;
- 二进制文件: 按自定义格式存储,没有字符编码含义(图片、exe 程序)。
Windows 依靠后缀名识别文件类型;Linux/Unix 不依赖后缀名识别文件类型。
2.文件权限:可读、可写、可执行,操作系统依靠权限机制保护数据安全,没有权限的用户不能做对应操作。
3.链接:Windows 快捷方式、Linux 软链接,本质是对真实文件的引用。
4.Unix/Linux 设计思想:万物皆文件,把磁盘、网卡、键盘显示器各类 I/O 设备全部抽象成文件,统一一套接口操作设备和普通磁盘文件。


2.5 文件系统做了什么总结
裸磁盘只有扇区;文件系统是一套软件规范:
- 在磁盘块上保存文件数据、元信息;
- 维护树形目录,维护文件名到文件实体的映射;
- 提供路径定位文件;
- 管理权限;
- 向上给应用程序提供打开、读、写、删除、创建目录等操作接口。
3. IO 的概念
IO 就是输入输出,程序和存储设备之间传输数据。课件用水池比喻 IO:
- 输入流(读):从文件读取数据到程序,如同从水池接水;
- 输出流(写):把程序的数据写入文件,如同向水池灌水。

缓冲区:IO 硬件速度慢,输出流会先把数据暂存内存缓冲区,缓冲区满才真正写磁盘。flush()强制把缓冲区数据刷入磁盘,避免数据留在内存丢失。
4. Java 对文件系统、IO 的封装
4.1 java.io.File 类
File类用来抽象描述一个文件 / 目录的路径。
⚠️创建 File 对象≠磁盘上真实存在这个文件,只是内存中的路径描述。
用核心方法:
表格
| 方法 | 作用 |
|---|---|
exists() |
判断文件 / 目录磁盘上是否真实存在 |
isFile() / isDirectory() |
判断是普通文件还是目录 |
createNewFile() |
创建空普通文件 |
delete() |
立刻删除文件;deleteOnExit()JVM 退出才删除 |
mkdir() |
创建单级目录;mkdirs()创建多级嵌套目录 |
listFiles() |
获取目录下所有子文件 File 对象 |
getAbsolutePath() / getCanonicalPath() |
获取绝对路径,canonic |
4.2 字节流: InputStream / OutputStream
针对原始字节读写,所有文件底层都是字节:
FileInputStream文件输入流:读文件字节;- read():读 1 个字节;
- read(byte[] buf):读到字节数组,批量读,减少 IO 系统调用,性能更好;
- 返回-1代表读到文件末尾;
FileOutputStream文件输出流:写文件字节;- write()系列写入字节 / 字节数组;
- 必须flush()刷新缓冲区 ;
- 流需要关闭释放资源,课件全部使用
try‑with‑resources语法,自动执行 close,避免资源泄露。
4.3 字符读写
直接用字节流处理中文文本很麻烦(需要手动处理 UTF‑8 编码):
- Scanner(InputStream, charset) :方便按字符读取文本;
- OutputStreamWriter :字节流转字符流,指定字符集;
- PrintWriter :包装后支持print / println / printf,写文本非常方便,写完记得flush()。
4.4 典型 IO 代码示例
- 读文件范式(字节批量读)
java
try (InputStream is=new FileInputStream("test.txt")){
byte[] buf=new byte[1024];
int len;
while ((len=is.read(buf))!=-1){
//本次读到的为有效字节
}
}
- 写文件范式
java
try (OutputStream os=new FileOutputStream("out.txt");
//字节->字符的转换器
OutputStreamWriter osw=new OutputStreamWriter(os,"UTF-8");
PrintWriter pw=new PrintWriter(osw)){
pw.println("测试内容");
pw.flush();
}
基于上面 API,可以实现:递归遍历目录、文件复制、查找文件名包含关键字的文件、检索文件内容关键字等小工具。文件系统是树形,扫描目录一般用深度优先递归遍历。
6. 总结
硬盘只是物理存储硬件,本身没有文件概念。文件系统是操作系统最重要抽象之一 :把冰冷磁盘扇区抽象为文件、目录、路径、权限。 IO 就是数据的流入流出;Java 中File负责描述文件元信息与路径,字节流、字符流负责文件内容读写。
"万物皆文件" 的思想,就是借助文件系统的抽象,把普通磁盘文件、硬件设备统一成同一套 IO 接口,极大简化上层应用开发。