发布时间:2026/6/14 0:05:13
22_Java缓冲流与转换流
Java缓冲流与转换流文章目录Java缓冲流与转换流前言一、缓冲流的原理二、字节缓冲流2.1 BufferedInputStream2.2 BufferedOutputStream三、字符缓冲流3.1 BufferedReader3.2 BufferedWriter四、转换流InputStreamReader五、转换流OutputStreamWriter六、流的装饰组合七、性能对比实验总结✅ 亮点总结适用场景扩展方向前言上一篇我们学习了Java IO流的体系框架和基础用法。在实际开发中直接使用FileInputStream和FileReader进行逐字节或逐字符读写效率较低因为每次read操作都会触发一次磁盘IO。Java提供了缓冲流和转换流来解决性能和编码问题。缓冲流通过内置缓存区减少实际IO次数转换流则在字节流和字符流之间架起桥梁。理解这两类流是掌握Java IO装饰器模式的关键一步。如果把基础流FileInputStream等看作水管缓冲流就是水塔——先把水存储起来再批量传输转换流则是翻译官——帮你在字节和字符之间进行编码转换。两者结合使用构成了Java IO编程中最常见的实践模式。本文将深入讲解这两类流的设计原理、使用方法和性能对比。一、缓冲流的原理普通IO流每次读/写操作都需要与底层设备交互产生大量系统调用性能较低。缓冲流内部维护了一个缓冲区数组。为了理解缓冲流的重要性可以做一个类比如果没有缓冲就相当于每次去银行只取1块钱一天要去100次有了缓冲就是一次取100块钱只去1次。系统调用的开销是IO性能的主要瓶颈而缓冲流正是通过批处理来减少这个开销。读操作一次性从磁盘读取大量数据到缓冲区后续read直接从缓冲区获取减少磁盘IO写操作数据先写入缓冲区当缓冲区满或调用flush()时才一次性写入磁盘// 缓冲流工作原理示意伪代码classBufferedInputStreamextendsFilterInputStream{byte[]bufnewbyte[8192];// 默认8KB缓冲区intcount;// 缓冲区有效字节数intpos;// 当前读取位置publicintread(){if(poscount){fill();// 缓冲区空了从底层流填充}returnbuf[pos];}}缓冲区大小默认是8192字节8KB可以通过构造方法自定义。二、字节缓冲流2.1 BufferedInputStreamimportjava.io.BufferedInputStream;importjava.io.FileInputStream;importjava.io.IOException;publicclassBufferedInputStreamDemo{publicstaticvoidmain(String[]args){longstart,end;// 不使用缓冲流读取startSystem.currentTimeMillis();try(FileInputStreamfisnewFileInputStream(D:/test/large_file.dat)){intdata;while((datafis.read())!-1){// 逐字节读取极慢}}catch(IOExceptione){e.printStackTrace();}endSystem.currentTimeMillis();System.out.println(无缓冲耗时(end-start)ms);// 使用缓冲流读取startSystem.currentTimeMillis();try(BufferedInputStreambisnewBufferedInputStream(newFileInputStream(D:/test/large_file.dat))){intdata;while((databis.read())!-1){// 同样逐字节读取但背后有缓冲区快很多}}catch(IOExceptione){e.printStackTrace();}endSystem.currentTimeMillis();System.out.println(有缓冲耗时(end-start)ms);}}装饰器模式体现在此BufferedInputStream包装了FileInputStream在不改变原有接口的前提下增强了功能。2.2 BufferedOutputStreamimportjava.io.BufferedOutputStream;importjava.io.FileOutputStream;importjava.io.IOException;publicclassBufferedOutputStreamDemo{publicstaticvoidmain(String[]args){try(BufferedOutputStreambosnewBufferedOutputStream(newFileOutputStream(D:/test/buffer_output.txt))){for(inti0;i1000;i){bos.write((第(i1)行数据\r\n).getBytes());// 数据先写入缓冲区减少磁盘IO次数}// flush()将缓冲区数据强制写入磁盘bos.flush();System.out.println(批量写入完成);}catch(IOExceptione){e.printStackTrace();}}}注意close()方法会自动调用flush()所以使用try-with-resources时通常不需要手动调用flush()。三、字符缓冲流3.1 BufferedReaderBufferedReader是字符缓冲输入流提供了逐行读取的便捷方法importjava.io.BufferedReader;importjava.io.FileReader;importjava.io.IOException;publicclassBufferedReaderDemo{publicstaticvoidmain(String[]args){try(BufferedReaderbrnewBufferedReader(newFileReader(D:/test/poem.txt))){Stringline;intlineNum1;// readLine() 逐行读取读到末尾返回nullwhile((linebr.readLine())!null){System.out.println((lineNum): line);}}catch(IOExceptione){e.printStackTrace();}}}readLine()方法是BufferedReader独有的其父类Reader中没有此方法这是缓冲流提供的重要增强。3.2 BufferedWriterimportjava.io.BufferedWriter;importjava.io.FileWriter;importjava.io.IOException;publicclassBufferedWriterDemo{publicstaticvoidmain(String[]args){try(BufferedWriterbwnewBufferedWriter(newFileWriter(D:/test/student_list.txt))){bw.write(学号\t姓名\t成绩);bw.newLine();// 写入系统相关的换行符跨平台兼容bw.write(001\t张三\t95);bw.newLine();bw.write(002\t李四\t88);bw.newLine();bw.write(003\t王五\t92);System.out.println(成绩单保存成功);}catch(IOExceptione){e.printStackTrace();}}}bw.newLine()是跨平台的换行方法会根据操作系统自动选择\r\nWindows或\nLinux/Mac。四、转换流InputStreamReaderInputStreamReader是字节流到字符流的桥梁它将字节输入流按照指定的字符编码转换为字符输入流importjava.io.*;publicclassInputStreamReaderDemo{publicstaticvoidmain(String[]args){// 读取GBK编码的文件Windows中文系统默认编码try(InputStreamReaderisrnewInputStreamReader(newFileInputStream(D:/test/gbk_file.txt),GBK);BufferedReaderbrnewBufferedReader(isr)){Stringline;while((linebr.readLine())!null){System.out.println(line);}}catch(IOExceptione){e.printStackTrace();}// 对比FileReader使用系统默认编码可能产生乱码try(BufferedReaderbrnewBufferedReader(newFileReader(D:/test/gbk_file.txt))){// 如果文件是GBK编码而系统默认是UTF-8此处就会乱码Stringlinebr.readLine();System.out.println(FileReader读取line);}catch(IOExceptione){e.printStackTrace();}}}关键理解FileReadernew InputStreamReader(new FileInputStream(...))使用系统默认编码当需要指定非默认编码时必须使用InputStreamReader五、转换流OutputStreamWriterOutputStreamWriter是字符流到字节流的桥梁importjava.io.*;publicclassOutputStreamWriterDemo{publicstaticvoidmain(String[]args){Stringcontent这是一段中文文本包含特殊字符 © ® ™;// 写入为UTF-8编码文件try(OutputStreamWriteroswnewOutputStreamWriter(newFileOutputStream(D:/test/utf8_output.txt),UTF-8);BufferedWriterbwnewBufferedWriter(osw)){bw.write(content);System.out.println(UTF-8文件写入成功);}catch(IOExceptione){e.printStackTrace();}// 写入为GBK编码文件相同内容不同编码try(OutputStreamWriteroswnewOutputStreamWriter(newFileOutputStream(D:/test/gbk_output.txt),GBK);BufferedWriterbwnewBufferedWriter(osw)){bw.write(content);System.out.println(GBK文件写入成功);}catch(IOExceptione){e.printStackTrace();}}}六、流的装饰组合Java IO流的核心设计模式是装饰器模式可以通过层层嵌套组合功能importjava.io.*;publicclassStreamDecoratorDemo{publicstaticvoidmain(String[]args)throwsIOException{// 经典三层装饰组合// FileInputStream(底层) → InputStreamReader(解码) → BufferedReader(缓冲按行读)try(BufferedReaderbrnewBufferedReader(newInputStreamReader(newFileInputStream(D:/test/data.txt),UTF-8))){Stringline;while((linebr.readLine())!null){System.out.println(line);}}// 写入组合// FileOutputStream(底层) → OutputStreamWriter(编码) → BufferedWriter(缓冲换行)try(BufferedWriterbwnewBufferedWriter(newOutputStreamWriter(newFileOutputStream(D:/test/result.txt),UTF-8))){bw.write(装饰器模式组合示例);bw.newLine();bw.write(灵活高效);}}}装饰器链条使得每种流只负责单一职责FileInputStream负责与文件交互InputStreamReader负责字节到字符的转换和编码BufferedReader负责缓冲和提供便利方法七、性能对比实验importjava.io.*;publicclassPerformanceTest{staticfinalStringSRCD:/test/large.dat;staticfinalStringDESTD:/test/copy.dat;publicstaticvoidmain(String[]args)throwsIOException{// 1. 基础字节流最慢testCopy(基础字节流,newFileInputStream(SRC),newFileOutputStream(DEST));// 2. 缓冲字节流testCopy(缓冲字节流,newBufferedInputStream(newFileInputStream(SRC)),newBufferedOutputStream(newFileOutputStream(DEST)));// 3. 自定义缓冲区字节流testCopy(自定义缓冲区(4KB),newFileInputStream(SRC),newFileOutputStream(DEST),4096);}staticvoidtestCopy(Stringname,InputStreamin,OutputStreamout)throwsIOException{longstartSystem.currentTimeMillis();try(in;out){byte[]bufnewbyte[1024];while(in.read(buf)!-1){out.write(buf);}}longendSystem.currentTimeMillis();System.out.println(name 耗时(end-start)ms);}staticvoidtestCopy(Stringname,InputStreamin,OutputStreamout,intbufSize)throwsIOException{longstartSystem.currentTimeMillis();try(in;out){byte[]bufnewbyte[bufSize];intlen;while((lenin.read(buf))!-1){out.write(buf,0,len);}}longendSystem.currentTimeMillis();System.out.println(name 耗时(end-start)ms);}}总结本文深入讲解了Java IO中的缓冲流与转换流缓冲流BufferedInputStream / BufferedOutputStream / BufferedReader / BufferedWriter通过内置缓冲区减少磁盘IO次数显著提升读写性能。BufferedReader的readLine()和BufferedWriter的newLine()是常用的便捷方法转换流InputStreamReader / OutputStreamWriter在字节流和字符流之间建立桥梁支持指定字符编码解决跨编码场景下的乱码问题装饰器模式Java IO通过层层包装组合不同流的功能实现了高度的灵活性和可扩展性在实际项目中推荐始终使用缓冲流包裹基础流并根据需要添加转换流来指定编码。✅ 亮点总结缓冲流内部默认8KB缓冲区的工作机制一次磁盘IO填充缓冲区后续read()直接从内存读取大幅减少系统调用BufferedReader/BufferedWriter提供的readLine()和newLine()便捷方法newLine()自动适配操作系统换行符InputStreamReader/OutputStreamWriter作为字节-字符桥梁核心价值在于允许显式指定字符编码GBK/UTF-8FileReader本质是new InputStreamReader(new FileInputStream(...), 默认编码)指定编码时需显式使用转换流装饰器模式三层经典组合底层FileStream文件交互→转换流编码处理→缓冲流性能优化便利方法适用场景大文件日志的逐行分析与数据统计利用BufferedReader逐行读取避免一次性加载跨编码系统的数据迁移如GBK编码的遗留系统数据转换为UTF-8存入新系统高效文件读写工具类的封装统一对外提供按行读取、批量写入等便捷接口扩展方向深入学习Java NIO的Channel与Buffer非阻塞IO理解BIO到NIO的架构升级研究Java 7 NIO.2的Files工具类Path、Files.copy/walk等现代化文件操作API推荐阅读23_Java序列化与反序列化上一篇[Java IO流体系详解](21_Java IO流体系详解.md) | 下一篇Java序列化与反序列化

相关新闻

Python soundcard库实战:手把手教你用电脑声卡搭建简易音频分析仪(附完整代码)
2026/6/13 6:39:01

Python soundcard库实战:手把手教你用电脑声卡搭建简易音频分析仪(附完整代码)

Python soundcard库实战:手把手教你用电脑声卡搭建简易音频分析仪(附完整代码)在电子工程和音频处理领域,专业音频分析设备往往价格昂贵,让许多爱好者和学生望而却步。但你可能不知道,通过Python的soundcar…

阅读更多
21_Java IO流体系详解
2026/6/7 7:56:48

21_Java IO流体系详解

Java IO流体系详解 文章目录Java IO流体系详解前言一、IO流的分类二、File类详解三、字节流:InputStream与OutputStream3.1 字节输入流 InputStream3.2 字节输出流 OutputStream3.3 文件拷贝示例四、字符流:Reader与Writer4.1 FileReader与FileWriter4.2…

阅读更多
AI赋能数据库开发:让快马平台的智能模型帮你优化MySQL查询与设计
2026/6/13 11:47:54

AI赋能数据库开发:让快马平台的智能模型帮你优化MySQL查询与设计

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 我正在开发一个用户订单分析系统,MySQL数据库中已有用户表和订单表。请分析并完成以下任务:1、根据常见的查询场景(如按时间段查询用户订单、统…

阅读更多
美国政府禁 Fable/Mythos,AI 市场或生变,大语言模型未来使用成谜?
2026/6/13 23:57:30

美国政府禁 Fable/Mythos,AI 市场或生变,大语言模型未来使用成谜?

美国政府禁 Fable/Mythos,AI 市场或将生变,未来大语言模型使用成谜?本来周五我打算放松一下,一边让智能代理帮我写代码,一边和朋友们看足球赛。我最近在做有趣的 HTML 游戏,还写了篇草稿文章探讨如何借助 A…

阅读更多
SpaceX上市首日大涨超19%,马斯克成全球首位万亿富豪,三张期权能否兑现?
2026/6/13 23:57:30

SpaceX上市首日大涨超19%,马斯克成全球首位万亿富豪,三张期权能否兑现?

SpaceX上市,马斯克成万亿富豪预料之中,SpaceX(SPCX.US)上市首日大涨超19%,公司市值突破2万亿美元。马斯克也因其在SpaceX和特斯拉的合计持股而成为全球首位万亿富豪。SpaceX上市挂牌定价每股150美元,也就是…

阅读更多
2026 年教程:Ubuntu 系统安装爱普生 V39 II 扫描仪驱动,简单几步即可使用!
2026/6/13 23:57:30

2026 年教程:Ubuntu 系统安装爱普生 V39 II 扫描仪驱动,简单几步即可使用!

【导语:2026 年 6 月 9 日发布的资讯提供了在 Ubuntu 系统上使用爱普生 Perfection V39 II 扫描仪的详细步骤,帮助用户解决安装和使用问题。】安装 qtbase5 - dev 软件包 要在 Ubuntu 系统使用爱普生 Perfection V39 II 扫描仪,首先需安装 qt…

阅读更多
EZRA:轻量级任务队列,支持多语言客户端,满足多种场景需求!
2026/6/13 23:57:30

EZRA:轻量级任务队列,支持多语言客户端,满足多种场景需求!

导航菜单切换导航。登录、外观设置。平台AI 代码创建:GitHub Copilot 借助 AI 编写更优质代码,GitHub Copilot 应用从问题到合并实现直接代理,MCP 注册表有新功能可集成外部工具。开发者工作流:Actions 自动化任何工作流&#xff…

阅读更多
无感知全域摸排 营区人员分布动态空间透明管理系统
2026/6/13 23:57:30

无感知全域摸排 营区人员分布动态空间透明管理系统

无感知全域摸排 营区人员分布动态空间透明管理系统一、系统综述镜像视界浙江科技有限公司依托国家十四五重点课题研究、镜像视界浙江普陀时空大数据应用技术联合研究院联合攻关、河南省电检院权威机构认证,打造面向智慧军营的无感知全域摸排 营区人员分布动态空间透…

阅读更多
如何深度定制iOS界面:解锁Misaka高级定制功能的完整指南
2026/6/13 22:57:30

如何深度定制iOS界面:解锁Misaka高级定制功能的完整指南

如何深度定制iOS界面:解锁Misaka高级定制功能的完整指南 【免费下载链接】misaka iOS & tvOS customisation tool for KFD & MDC 项目地址: https://gitcode.com/gh_mirrors/mis/misaka Misaka作为一款专为KFD和MDC打造的iOS与tvOS深度定制工具&…

阅读更多
GIT修改用户名
2026/6/13 10:50:23

GIT修改用户名

在GIT中修改用户名可按以下步骤操作: 查看当前git的用户名,使用命令git config --list或git config user.name。修改git用户名,使用命令git config --global user.name "xxx(新的用户名)",将其中…

阅读更多
Win11Debloat:让你的Windows系统重获新生的终极优化工具
2026/6/13 15:45:46

Win11Debloat:让你的Windows系统重获新生的终极优化工具

Win11Debloat:让你的Windows系统重获新生的终极优化工具 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter and …

阅读更多
技术深度解析:m4s-converter实现原理与B站缓存视频转换最佳实践
2026/6/13 11:10:35

技术深度解析:m4s-converter实现原理与B站缓存视频转换最佳实践

技术深度解析:m4s-converter实现原理与B站缓存视频转换最佳实践 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter m4s-converter是一个…

阅读更多