Java IO(输入输出)是程序与磁盘、网络、外设进行数据交互的核心基础,所有文件读写、网络传输、数据持久化功能均依赖IO体系实现。Java IO历经迭代,从传统阻塞IO演进到NIO非阻塞IO、AIO异步IO,最终衍生出高性能网络框架Netty。
本文系统化覆盖六大核心模块:File文件操作、字节/字符IO流、BIO/NIO/AIO三大IO模型、NIO核心三大组件、Netty核心原理,从底层机制、语法规范、实战代码、易错坑点到大厂面试真题全覆盖,适配日常开发、笔试面试、网络编程进阶全场景。
一、File 文件操作类(磁盘文件基础)
File 类是 Java 对磁盘文件、文件夹路径的抽象封装,专门用于操作文件元数据,可实现文件创建、删除、重命名、路径判断、目录遍历等操作。注意:File 仅操作文件属性,不具备文件读写能力,文件内容读写需要依赖IO流。
1.1 File 核心构造方法
// 传入文件/目录路径
File file1 = new File("D:/test.txt");
// 父路径+子文件名
File file2 = new File("D:/file", "test.txt");
1.2 核心常用方法
判断类方法:
exists():判断文件/目录是否存在;isFile():判断是否为文件;isDirectory():判断是否为文件夹;canRead()/canWrite():判断读写权限
创建删除方法:
createNewFile():创建空文件;mkdir():创建单层目录;mkdirs():创建多层目录;delete():删除文件/空文件夹
获取信息方法:
getName():获取文件名;getPath():获取相对路径;getAbsolutePath():获取绝对路径;length():获取文件字节大小
1.3 核心易错点
1、mkdir() 仅能创建单层目录,多级目录创建失败,mkdirs() 可创建多级目录,开发优先使用;
2、delete() 删除文件夹时,仅能删除空文件夹,非空文件夹无法直接删除;
3、File 对象创建成功,不代表磁盘文件一定存在,必须通过 exists() 判断。
本节面试真题
题目:File类能不能读写文件内容?mkdir和mkdirs的区别?
答案:File类仅操作文件元数据,无法读写文件内容;mkdir只能创建单层目录,多级目录创建失败;mkdirs可创建任意层级的多级目录,日常开发优先使用。
二、传统IO流体系(BIO核心)
IO 流是 Java 数据传输的核心载体,用于实现文件、网络的数据读写。传统 IO 按照数据类型分为字节流、字符流,按照传输方向分为输入流、输出流,是 BIO 阻塞编程的核心基础。
2.1 字节流(InputStream / OutputStream)
字节流是 IO 底层通用流,以 字节(byte) 为单位传输数据,可处理所有类型文件(文本、图片、视频、音频、压缩包),适配所有二进制数据传输场景。
核心子类:FileInputStream、FileOutputStream(文件字节流,最常用)
// 字节流文件拷贝(通用所有文件)
public class IOUtil {
public static void copyFile(String src, String dest) throws IOException {
try (InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest)){
byte[] buffer = new byte[1024];
int len;
// 循环读取字节数据
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
}
}
}
2.2 字符流(Reader / Writer)
字符流以 字符(char) 为单位传输数据,专门用于处理纯文本文件(txt、java、md、yml),底层基于字节流+编码解析,自动适配字符编码,避免中文乱码。
核心子类:FileReader、FileWriter、BufferedReader、BufferedWriter
// 字符流读取文本文件
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))){
String line;
// 按行读取,效率更高
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
2.3 字节流与字符流核心区别(面试必考)
1、传输单位:字节流以byte为单位,字符流以char为单位;
2、适用场景:字节流处理所有二进制文件,字符流仅处理纯文本文件;
3、编码处理:字节流不处理编码,易乱码;字符流自带编码解析,适配中文;
4、缓冲区:字符流默认带缓冲区,需手动flush刷新;字节流无默认缓冲区。
2.4 IO流核心规范
1、IO 资源属于系统资源,必须手动关闭,JVM 无法自动回收;
2、JDK7+ 推荐 try-with-resources 语法,自动关闭流,规避资源泄漏;
3、读写完成后必须刷新缓冲区,避免数据残留丢失。
三、三大IO模型:BIO / NIO / AIO
Java 共计三种IO编程模型,核心差异在于阻塞方式、线程模型、并发能力、适用场景,是网络编程、中间件、Netty面试的核心重难点。
3.1 BIO(同步阻塞IO)
核心特性:同步、阻塞、一连接一线程
客户端发起连接后,服务端单独开启一个线程处理,线程在等待连接、读取数据、写入数据全程阻塞,无数据时线程一直等待。
优点:代码简单、通俗易懂、适合小型程序;
致命缺点:并发能力极差,海量连接下线程暴涨,CPU上下文切换频繁,服务宕机;
适用场景:连接数少、短连接、低并发业务。
3.2 NIO(同步非阻塞IO,JDK1.4+)
核心特性:同步、非阻塞、单线程多路复用
NIO 彻底重构IO体系,摒弃一连接一线程模型,通过选择器复用单线程管理海量连接,线程不会阻塞等待数据,无数据时线程可处理其他任务。
优点:并发能力极强、线程资源极少、适配高并发场景;
缺点:原生NIO代码极其繁琐、BUG多(空轮询BUG)、开发成本高;
适用场景:高并发、长连接、海量连接的网络编程场景。
3.3 AIO(异步非阻塞IO,JDK1.7+)
核心特性:异步、非阻塞、操作系统回调通知
全程无需线程等待数据,由操作系统完成数据读取、写入后,主动回调程序方法处理业务,是最理想的IO模型。
优点:性能最高、无需线程轮询、资源利用率极致;
缺点:Windows支持完善,Linux支持极差,生产几乎不用;
现状:Java AIO 基本废弃,主流高并发框架均基于NIO实现。
本节面试真题
题目:BIO、NIO、AIO的核心区别?为什么生产不用AIO?
答案:BIO同步阻塞、一连接一线程、低并发;NIO同步非阻塞、多路复用、高并发;AIO异步非阻塞、系统回调、性能最优。AIO在Linux系统支持不完善,兼容性差,生产环境无落地场景,因此主流技术栈均基于NIO。
四、NIO 三大核心组件(Buffer/Channel/Selector)
NIO 整体架构由三大核心组件构成:Buffer(缓冲区)、Channel(通道)、Selector(选择器),三者配合实现多路复用非阻塞IO,是Netty框架的底层基石。
4.1 Buffer 缓冲区(数据容器)
Buffer 是 NIO 的数据存储载体,所有读写数据必须先存入缓冲区,本质是封装后的数组,支持双向读写,区别于BIO单向流。
核心子类:ByteBuffer(最常用)、CharBuffer、IntBuffer、FloatBuffer
四大核心属性:
position:当前读写位置;limit:读写边界;capacity:缓冲区最大容量;mark:标记回溯位置
核心方法:flip()(切换读模式)、clear()(清空缓冲区)、rewind()(重读数据)
4.2 Channel 通道(数据传输通道)
Channel 是 NIO 数据传输的通道,对接文件、网络端口,负责连接数据源与缓冲区,双向可读可写、非阻塞、可复用。
核心子类:FileChannel(文件通道)、SocketChannel(客户端网络通道)、ServerSocketChannel(服务端网络通道)
核心特性:BIO流单向传输,Channel双向传输;支持异步读写;可配合缓冲区实现零拷贝。
4.3 Selector 选择器(多路复用核心)
Selector 是 NIO 多路复用的核心,单线程管理多个Channel,轮询监听所有通道的事件(连接、读、写),仅处理就绪的通道,彻底解决BIO线程资源浪费问题。
核心监听事件:
OP_ACCEPT:客户端连接事件;OP_READ:数据可读事件;OP_WRITE:数据可写事件
工作流程:Channel注册到Selector -> Selector轮询就绪事件 -> 单线程处理所有就绪通道
4.4 NIO 原生痛点(Netty诞生原因)
1、原生NIO存在空轮询BUG,导致CPU 100%占用;
2、API繁琐、底层复杂、手动维护缓冲区、读写逻辑冗余;
3、无断线重连、心跳检测、粘包拆包机制,生产无法直接使用。
五、Netty 高性能网络框架(NIO实战落地)
Netty 是基于 Java NIO 封装的高性能、高可靠、事件驱动的网络编程框架,彻底解决原生NIO的BUG与开发痛点,是目前 Java 网络编程、RPC框架、中间件(Redis、Dubbo、RocketMQ)的底层核心依赖。
5.1 Netty 核心优势
1、修复原生NIO空轮询BUG,杜绝CPU飙高问题;
2、封装极简API,屏蔽底层NIO复杂逻辑,开发效率大幅提升;
3、内置粘包拆包、心跳检测、断线重连、流量控制机制;
4、基于主从多线程模型,并发性能极致优化;
5、支持零拷贝、内存池、对象池,资源利用率极高。
5.2 Netty 核心组件
1、Bootstrap/ServerBootstrap:客户端/服务端启动引导器,封装启动配置、绑定端口、注册处理器;
2、EventLoopGroup:事件循环组,核心线程池,负责轮询IO事件、执行任务;
3、ChannelPipeline:责任链管道,管理处理器执行顺序,实现编解码、业务处理;
4、ChannelHandler:业务处理器,处理读写、异常、连接事件;
5、ByteBuf:Netty自定义缓冲区,替代原生ByteBuffer,性能更强、操作更便捷。
5.3 Netty 主从线程模型(核心面试点)
BossGroup(主线程组):负责监听端口、接收客户端连接,不处理业务;
WorkerGroup(从线程组):负责处理已建立连接的读写事件、执行业务逻辑;
优势:连接接收与业务处理线程隔离,分工明确,高并发、高吞吐、低延迟。
5.4 粘包与拆包问题(生产高频)
问题成因:TCP是流式协议,无数据边界,多条数据会粘连、单条数据会拆分;
Netty解决方案:固定长度解码器、行解码器、自定义分隔符、长度域解码器(生产主流)。
本节面试真题
题目:Netty为什么比原生NIO性能好?
答案:Netty修复NIO空轮询BUG;优化线程模型实现高并发;内置内存池、零拷贝提升IO效率;封装完善的故障处理、粘包拆包机制;API简洁、稳定性强,适配生产高并发场景。
六、全文终极背诵总结(面试必背)
1、File类:仅操作文件元数据,不负责读写,mkdirs支持多级目录创建,是文件操作基础;
2、IO流:字节流通吃所有文件,字符流专属文本文件,BIO为同步阻塞单向流,必须手动关闭资源;
3、IO模型:BIO一连接一线程低并发,NIO多路复用高并发,AIO异步高效但Linux不兼容、生产废弃;
4、NIO核心:Buffer存数据、Channel传数据、Selector多路监听,单线程管理海量连接,是高并发IO核心;
5、Netty框架:基于NIO优化,修复原生BUG,主从线程模型,内置粘包拆包、心跳检测,是主流网络编程框架。