目录
[二、File 类:文件 / 目录的「管理员」](#二、File 类:文件 / 目录的「管理员」)
[1. 核心作用](#1. 核心作用)
[2. 常用构造方法](#2. 常用构造方法)
[3. 高频实用方法(背会就能用)](#3. 高频实用方法(背会就能用))
[4. 实战:创建文件 + 遍历目录](#4. 实战:创建文件 + 遍历目录)
[三、字节流:InputStream/OutputStream 数据读写](#三、字节流:InputStream/OutputStream 数据读写)
[1. OutputStream:写数据(FileOutputStream)](#1. OutputStream:写数据(FileOutputStream))
[2. InputStream:读数据(FileInputStream)](#2. InputStream:读数据(FileInputStream))
[3. 终极实战:文件复制(字节流最经典用法)](#3. 终极实战:文件复制(字节流最经典用法))
做文件操作、数据读写是 Java 开发里最常用、最基础的功能,我刚学的时候总把这几个类搞混,今天就用最直白的话,把 File(文件 / 目录操作) 、InputStream(字节输入流) 、OutputStream(字节输出流) 的用法、区别、实战场景一次性讲清楚,不搞花里胡哨的理论,全是能直接用的代码和经验。
一、先搞懂核心定位:它们分别是干嘛的?
先别着急写代码,先分清三个类的「分工」,这是最关键的:
- File 类 :不负责读写数据,只负责「管文件 / 目录本身」------ 创建文件 / 文件夹、删除、重命名、判断是否存在、获取路径等。
- InputStream 字节输入流 :读数据 ------ 从文件、网络等源头,把数据「读进」Java 程序。
- OutputStream 字节输出流 :写数据 ------ 把 Java 程序里的数据「写出」到文件、网络等目标。
一句话总结:File 管文件本身,流管数据读写。
二、File 类:文件 / 目录的「管理员」
1. 核心作用
- 表示一个文件 或 文件夹 的路径(可以是存在的,也可以是不存在的)
- 操作文件 / 目录的属性:创建、删除、判断类型、获取大小、列出子文件等
- 绝对不能用它读写文件内容!
2. 常用构造方法
直接传路径字符串,支持相对路径(相对于项目根目录)和绝对路径:
java
// 相对路径:项目根目录下的 test.txt
File file = new File("test.txt");
// 绝对路径:完整磁盘路径
File file = new File("D:\\test\\demo.txt");
// 拼接路径:父目录 + 子文件名
File parentDir = new File("D:\\test");
File file = new File(parentDir, "demo.txt");
小技巧:Windows 路径用
\\或/都可以,推荐/跨系统通用。
3. 高频实用方法(背会就能用)
这些是开发中 90% 会用到的,直接记:
java
File file = new File("test.txt");
// 1. 判断文件/目录是否存在
boolean exists = file.exists();
// 2. 创建文件(不存在则创建,存在返回 false)
boolean createSuccess = file.createNewFile();
// 3. 创建单级文件夹
boolean mkdirSuccess = file.mkdir();
// 创建多级文件夹(比如 a/b/c,推荐用这个)
boolean mkdirsSuccess = file.mkdirs();
// 4. 删除文件/空目录
boolean deleteSuccess = file.delete();
// 5. 判断是文件还是目录
boolean isFile = file.isFile();
boolean isDir = file.isDirectory();
// 6. 获取文件信息
String name = file.getName(); // 文件名
String path = file.getAbsolutePath(); // 绝对路径
long size = file.length(); // 文件大小(字节)
// 7. 列出目录下的所有子文件
File[] files = file.listFiles();
4. 实战:创建文件 + 遍历目录
举两个最常用的实战代码,直接复制就能跑:
(1)安全创建文件(先判断,再创建)
java
public static void createFile() throws IOException {
File file = new File("D:/test/demo.txt");
// 先判断父目录是否存在,不存在就创建
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
// 创建文件
if (!file.exists()) {
file.createNewFile();
System.out.println("文件创建成功");
} else {
System.out.println("文件已存在");
}
}
(2)遍历目录下所有文件
java
public static void listDirectory() {
File dir = new File("D:/test");
if (dir.isDirectory()) {
File[] files = dir.listFiles();
if (files != null) {
for (File f : files) {
System.out.println((f.isFile() ? "文件:" : "目录:") + f.getName());
}
}
}
}
三、字节流:InputStream/OutputStream 数据读写
File 管完文件,读写数据就靠字节流 ,这是 Java IO 最底层的流,所有文件(文本、图片、视频、音频)都能用它读写。
先记两个核心规则:
- InputStream :抽象类,不能直接 new,用子类
FileInputStream读文件- OutputStream :抽象类,不能直接 new,用子类
FileOutputStream写文件- 流用完必须关闭,否则会占用系统资源,推荐用 try-with-resources 自动关闭。
1. OutputStream:写数据(FileOutputStream)
作用:把数据写到文件里,覆盖写 / 追加写都支持。
核心方法
java
// 1. 创建流:默认覆盖原文件内容
FileOutputStream fos = new FileOutputStream("test.txt");
// 2. 追加写:第二个参数传 true
FileOutputStream fos = new FileOutputStream("test.txt", true);
// 3. 写数据
fos.write(97); // 写单个字节(97 对应字符 'a')
fos.write("Hello IO".getBytes()); // 写字符串(转字节数组)
fos.write("Hello IO".getBytes(), 0, 5); // 写部分字节
// 4. 刷新缓冲区(强制把数据写到文件)
fos.flush();
// 5. 关闭流(必须做)
fos.close();
实战:自动关闭流的标准写法(推荐)
java
public static void writeFile() {
// try-with-resources:流会自动关闭,不用手动写 close()
try (FileOutputStream fos = new FileOutputStream("test.txt")) {
// 写字符串
fos.write("这是我用字节流写的内容".getBytes());
System.out.println("写入成功");
} catch (IOException e) {
e.printStackTrace();
}
}
2. InputStream:读数据(FileInputStream)
作用:从文件里把数据读进 Java 程序,一次读一个字节 / 一个字节数组。
核心方法
java
FileInputStream fis = new FileInputStream("test.txt");
// 1. 读单个字节:返回字节值,读到文件末尾返回 -1
int b = fis.read();
// 2. 读字节数组:返回读到的字节数,末尾返回 -1
byte[] buffer = new byte[1024]; // 缓冲区(常用 1024 字节)
int len = fis.read(buffer);
// 3. 关闭流
fis.close();
实战:读取文件内容
java
public static void readFile() {
try (FileInputStream fis = new FileInputStream("test.txt")) {
byte[] buffer = new byte[1024];
int len;
// 循环读取,直到返回 -1(读完)
while ((len = fis.read(buffer)) != -1) {
// 把字节数组转成字符串
String content = new String(buffer, 0, len);
System.out.println("读取内容:" + content);
}
} catch (IOException e) {
e.printStackTrace();
}
}
3. 终极实战:文件复制(字节流最经典用法)
字节流最大的用途就是复制任意格式文件(图片、视频都能复制),这是面试和工作必写的代码:
java
public static void copyFile(String srcPath, String destPath) {
// 源文件:读 目标文件:写
try (FileInputStream fis = new FileInputStream(srcPath);
FileOutputStream fos = new FileOutputStream(destPath)) {
byte[] buffer = new byte[1024 * 4]; // 4KB 缓冲区
int len;
// 边读边写
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
System.out.println("文件复制成功");
} catch (IOException e) {
e.printStackTrace();
}
}
// 调用:复制图片
copyFile("D:/test/photo.jpg", "D:/test/photo_copy.jpg");
四、关键注意事项
- File 不能读写数据:很多新手犯的错,用 File 试图读文件内容,这是完全错误的。
- 流一定要关闭:用 try-with-resources 最安全,自动关闭,不用手动处理异常。
- 字节流是万能流:不管是文本、图片、视频、压缩包,都能用 InputStream/OutputStream 处理。
- 覆盖写 vs 追加写 :
new FileOutputStream(file)默认覆盖,加true才是追加。- 路径问题:相对路径是相对于项目根目录,绝对路径要写完整,注意父目录不存在会报错。
五、一张表总结核心区别
| 类 | 定位 | 核心功能 | 能否读写数据 |
|---|---|---|---|
| File | 文件 / 目录抽象表示 | 创建、删除、判断、获取属性 | ❌ 不能 |
| FileInputStream | 字节输入流(读) | 从文件读取字节数据 | ✅ 只读 |
| FileOutputStream | 字节输出流(写) | 向文件写入字节数据 | ✅ 只写 |
总结
- File 负责文件 / 目录本身的增删改查,和数据读写无关;
- InputStream/OutputStream 是字节流,负责数据读写,支持所有文件类型;
- 实战优先用
try-with-resources自动关闭流,复制文件用字节流最稳妥;- 新手先把这三个类的基础用法练熟,后续学字符流、缓冲流都会轻松很多。
这都是我实际开发中天天用的知识点,没有多余理论,照着代码练两遍,Java IO 基础就稳了。