news 2026/9/3 5:24:22

Java IO 完整学习笔记|字节流、字符流、缓冲流、资源关闭全梳理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java IO 完整学习笔记|字节流、字符流、缓冲流、资源关闭全梳理

一、IO流整体体系

Java IO两大分支:字节流字符流,所有流都实现AutoCloseable接口,支持try‑with‑resources自动关闭。

分类输入(读)输出(写)处理单元
字节流InputStreamOutputStreambyte 字节
字符流ReaderWriterchar 字符

1. 字节流:万能二进制流

父类:InputStream/OutputStream常用实现:FileInputStreamFileOutputStream

✅ 适用:所有文件:图片、视频、压缩包、文档。直接操作原始二进制,不会做编码转换。

核心API
//读:返回int,-1代表读到文件末尾 int read(); //读取1个字节 int read(byte[] buffer); //批量读到字节数组,返回读到字节数 //写 void write(int b); //写单个字节 void write(byte[] b); //写整个字节数组 void write(byte[] b,int off,int len); //数组指定范围写入

⚠️重点:read()返回int而不是byte字节范围‑128~127,如果读到字节0xFF,强转byte等于‑1,会和文件结束标记‑1冲突。所以用int接收,高24位补0,用‑1代表流结束。

FileOutputStream构造第二个参数:true=追加写入;不传/false=覆盖原文件。

2. 字符流:专门处理文本

父类:Reader/Writer常用实现:FileReaderFileWriter

✅适用:纯文本文件.txt.java.md) ❌禁止处理图片视频等二进制文件,会直接损坏文件。

底层本质:字符流 = 字节流 + 编码解码,把字节按照字符集转成char。

核心API
int read(); //读1个字符,返回‑1结束 int read(char[] cbuf); //批量读到字符数组 void write(int c); void write(char[] cbuf); void write(String str);

⚠️字符流自带内存缓冲区! 数据先写到内存缓冲区,没有调用flush()或者close(),数据不会落到磁盘,会出现文件空白、数据丢失。

  • flush():强制把缓冲区数据刷到磁盘
  • close():关闭流,关闭前自动执行flush

3. 转换流:解决编码问题

FileReader / FileWriter会直接使用系统默认编码,跨平台会乱码。想要手动指定编码,使用转换流。

  • InputStreamReader:字节输入流 → 字符输入流,指定编码读文件
  • OutputStreamWriter:字节输出流 → 字符输出流,指定编码写文件
//示例:指定UTF‑8读取文本 try(InputStreamReader isr = new InputStreamReader(new FileInputStream("test.txt"), StandardCharsets.UTF_8)){ }

二、缓冲流:提升读写性能

原始FileXXX流读写频繁磁盘IO,性能差。缓冲流增加内存缓冲区,减少磁盘交互,大幅提升效率,属于包装流,必须包裹原始流。

字节缓冲流字符缓冲流
BufferedInputStreamBufferedReader
BufferedOutputStreamBufferedWriter
//字节缓冲流示例 try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream("test.jpg"))){ }

BufferedReader特有方法:readLine(),直接读取一行字符串,非常适合文本处理。BufferedWriter特有方法:newLine(),写入换行符。

缓冲流底层:默认缓冲区大小8192字节,数据先填满缓冲区,再一次性操作磁盘,减少IO次数。

三、资源关闭:两种写法

流不关闭会造成文件句柄泄漏,程序长时间运行打开大量文件,服务直接崩溃。

1. 传统 try‑finally

FileInputStream fis = null; try { fis = new FileInputStream("a.txt"); //读写操作 } catch (IOException e) { e.printStackTrace(); } finally { if(fis != null){ fis.close(); } }

缺陷:try块和finally块同时抛出异常,原始异常会被掩盖丢失。

2. Java7+ try‑with‑resources【推荐】

只要实现AutoCloseable接口,在try()括号中定义流对象,代码结束自动关闭资源,不需要手动finally

try(FileInputStream fis = new FileInputStream("a.txt"); BufferedInputStream bis = new BufferedInputStream(fis)){ //读写 }catch (IOException e){ e.printStackTrace(); }

✅代码简洁、自动释放、不会丢失原始异常,开发优先使用。

❌误区:return不会关闭流!return只是方法返回,不会释放文件句柄。

四、字节流 vs 字符流完整对比

对比维度字节流字符流
顶层抽象InputStream / OutputStreamReader / Writer
操作单元byte字节char字符
底层原理直接读写二进制字节流+编码集转换
自带缓冲区无(缓冲流额外包装)自带缓冲区
flush行为不需要flush必须flush/close落盘
适用文件图片、视频、压缩包,全部文件txt、源码等纯文本
乱码风险无编码转换,不会乱码编码不匹配直接乱码

五、总结

  1. read()返回值是int,判断结束条件==‑1,不要强转byte/char再判断。
  2. 字符流忘记flush/close,文件为空,数据丢失。
  3. FileWriter追加模式:构造传入第二个参数true,否则每次覆盖旧文件。
  4. FileReader/FileWriter跟随系统编码,跨平台乱码,指定编码优先用转换流。
  5. 不要拿字符流读取二进制文件,文件直接损坏。
  6. 流资源务必释放,优先try‑with‑resources,杜绝句柄泄漏。
  7. 缓冲流是包装流,关闭外层缓冲流即可,内层被包装流会自动关闭。
  8. 文件路径:Windows路径需要转义D:\\demo.txt,也可以写D:/demo.txt

六、补充:File类

File类不负责文件内容读写,只用来表示文件/目录路径,完成创建、删除、重命名、判断是否存在、遍历目录等操作。 常用方法:

  • exists()判断文件是否存在
  • createNewFile()创建文件
  • mkdir()/mkdirs()创建单级/多级目录
  • delete()删除文件
  • listFiles()遍历目录下全部子文件

File不能读写文件内容,读写必须依靠IO流。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 5:23:40

异程度对比实战:多方案多时期下的统计评估与Python实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 5:23:16

C盘爆红怎么办?开源清理工具与磁盘空间分析实战指南

每当电脑右下角弹出一条“C盘空间不足”的通知,或者资源管理器里的系统盘图标突然变成红色时,很多人第一反应就是下载一个所谓的“清理大师”。可这类软件往往不仅带弹窗广告,还要你开通会员才能体验“完整清理功能”,最后还可能捆…

作者头像 李华
网站建设 2026/9/3 5:22:42

互感线圈同名端:从原理到实战,避免电路设计中的隐形陷阱

你有没有遇到过这种情况:电路仿真跑得好好的,一搭实物就啸叫、发热,甚至烧芯片?辛辛苦苦算出来的谐振频率,实测值和理论值差了十万八千里,调来调去就是不对。很多时候,问题就出在一个看似不起眼…

作者头像 李华
网站建设 2026/9/3 5:21:14

生物信息学高效学习路径:项目驱动与实战闭环解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 5:16:49

学习机芯片性能实测:从《我的世界》看作业帮学习机的真实水平

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华