Java IO 基础

背景与动机#

IO 用于让程序和外部世界交换数据,例如读写文件、处理网络数据、读取配置等。

Java IO 学习时先抓住两条主线:

  • 字节流:处理原始字节,适合图片、压缩包、二进制文件。
  • 字符流:处理文本字符,适合文本文件。

核心原理拆解#

1. 字节流和字符流#

img
img

字节流常见抽象:

  • InputStream
  • OutputStream

字符流常见抽象:

  • Reader
  • Writer

如果处理文本,优先关注字符编码;如果处理二进制数据,优先使用字节流。

2. IO 流还可以怎么分类#

除了字节流 / 字符流,面试和文档里还常从下面三个角度划分:

划分方式分类说明
按流向输入流、输出流数据读入还是写出
按操作单元字节流、字符流按字节还是按字符处理
按角色节点流、处理流直接连数据源,还是包一层增强功能

常见基类:

  • 字节流:InputStreamOutputStream
  • 字符流:ReaderWriter

处理流例如 BufferedReaderBufferedInputStream,用来缓冲、提速,本身不直接连文件。

img
img

BIO、NIO、AIO 以及 Netty 属于网络 IO 模型专题,内容较多,见 Java BIO、NIO、AIO 与 Netty

3. Files 工具类适合简单文件操作#

读取文本:

String text = Files.readString(Path.of("demo.txt"));

写入文本:

Files.writeString(Path.of("demo.txt"), "hello");

对于小文件和学习场景,Files 非常直接。

常用方法速查:

方法作用
Files.exists()判断路径是否存在
Files.createFile()创建新文件
Files.createDirectory()创建目录
Files.delete()删除文件或目录
Files.deleteIfExists()存在则删除
Files.copy()复制文件
Files.move()移动/重命名
Files.size()查看文件大小
Files.readString()一次性读文本
Files.writeString()一次性写文本
Files.newBufferedReader()按行读取
Files.newBufferedWriter()缓冲写入

示例:

Path path = Path.of("demo.txt");
if (!Files.exists(path)) {
Files.createFile(path);
}
Files.writeString(path, "hello");
System.out.println(Files.size(path));
Files.copy(path, Path.of("demo-copy.txt"));
Files.deleteIfExists(path);

4. try-with-resources 自动关闭资源#

try (BufferedReader reader = Files.newBufferedReader(Path.of("demo.txt"))) {
String line = reader.readLine();
System.out.println(line);
}

放在 try (...) 中的资源会在代码块结束后自动关闭,减少资源泄漏风险。

5. IO 操作通常会抛出异常#

文件不存在、没有权限、磁盘异常等都可能导致 IO 失败。所以很多 IO API 会抛出 IOException,调用方需要处理或继续声明。

最小可运行代码示例#

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class IoDemo {
public static void main(String[] args) throws IOException {
Path path = Path.of("demo.txt");
Files.writeString(path, "hello java");
String text = Files.readString(path);
System.out.println(text);
Files.deleteIfExists(path);
}
}

常见陷阱与错误示例#

1. 忘记关闭流#

手动打开流后不关闭,可能导致文件句柄泄漏。优先使用 try-with-resources。

2. 忽略字符编码#

文本读写如果编码不一致,可能出现乱码。真实项目中应明确输入输出编码策略。

3. 把大文件一次性读进内存#

Files.readString 适合小文件。大文件应考虑逐行读取或分块处理。

面试高频问题#

1. Java 中 IO 流分几种#

可按流向分输入/输出,按单元分字节/字符,按角色分节点流/处理流。基类是 InputStream/OutputStreamReader/Writer

2. 字节流和字符流有什么区别#

字节流处理原始字节,适合二进制数据;字符流处理字符,适合文本数据,并涉及字符编码。

3. try-with-resources 解决什么问题#

它能自动关闭实现了 AutoCloseable 的资源,减少忘记关闭流导致的资源泄漏。

4. BIO、NIO、AIO 有什么区别#

Java BIO、NIO、AIO 与 Netty 专题笔记。

5. Files 常用方法有哪些#

常见有 existscreateFilecreateDirectorydeletecopymovesizereadStringwriteStringnewBufferedReader 等,适合简单文件读写。

6. 为什么 IO 方法常常要处理 IOException#

因为文件和外部资源不完全受程序控制,可能出现不存在、无权限、读写失败等情况。

一句话总结#

Java IO 的基础判断是:文本优先字符和编码,二进制优先字节;资源打开后要可靠关闭,简单文件读写可以先用 Files。网络 IO 模型与 Netty 见专题笔记。

文章目录

文章目录