发布时间:2026/6/14 1:45:39
21_Java IO流体系详解
Java IO流体系详解文章目录Java IO流体系详解前言一、IO流的分类二、File类详解三、字节流InputStream与OutputStream3.1 字节输入流 InputStream3.2 字节输出流 OutputStream3.3 文件拷贝示例四、字符流Reader与Writer4.1 FileReader与FileWriter4.2 字节流与字符流的桥接五、try-with-resources 自动关闭资源六、IO流使用的最佳实践总结✅ 亮点总结适用场景扩展方向前言在Java开发中IOInput/Output流是处理数据输入输出的核心机制。无论是文件读写、网络通信还是内存数据处理都离不开IO流的支持。Java的IO流体系设计精良采用装饰器模式构建了一套灵活、可扩展的流处理框架。Java IO流体系是初学者最容易产生学完就忘的知识点之一原因在于种类太多、API繁杂。但实际上如果你理解了它的设计模式——装饰器模式——整个体系就变得有条理了。就像乐高积木一样基础流负责连接数据源功能流缓冲、转换、编码负责增强能力通过层层嵌套组合出任意你需要的功能。本文将从零开始系统讲解Java IO流的分类、核心类及其使用方法帮助你建立清晰的IO流心智模型。一、IO流的分类Java IO流可以从两个维度进行分类按数据流向分输入流InputStream/Reader和输出流OutputStream/Writer按处理单位分字节流以byte为单位和字符流以char为单位分类字节输入流字节输出流字符输入流字符输出流抽象基类InputStreamOutputStreamReaderWriter文件操作FileInputStreamFileOutputStreamFileReaderFileWriter缓冲操作BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter设计理念字节流适合处理二进制数据图片、视频、音频字符流适合处理文本数据内置了字符编码处理。二、File类详解File类是java.io包中唯一代表磁盘文件本身的对象它既可以表示文件也可以表示目录。需要注意的是File类只用于表示文件目录的信息名称、大小、路径等不能用于文件内容的读写。常见的混淆点很多初学者误以为new File(test.txt)会创建文件。实际上构造File对象只是在内存中创建一个代表路径的对象并不会在磁盘上创建任何东西。磁盘上的文件创建需要通过createNewFile()方法显式完成。此外File类既可以表示文件也可以表示目录需要通过isDirectory()和isFile()方法来判断。importjava.io.File;importjava.io.IOException;importjava.util.Date;publicclassFileDemo{publicstaticvoidmain(String[]args)throwsIOException{// 创建File对象三种方式Filefile1newFile(D:/test/hello.txt);// 绝对路径Filefile2newFile(D:/test,hello.txt);// 父目录 子路径FileparentnewFile(D:/test);Filefile3newFile(parent,hello.txt);// 父File对象 子路径System.out.println(文件是否存在file1.exists());System.out.println(文件名file1.getName());System.out.println(父路径file1.getParent());System.out.println(绝对路径file1.getAbsolutePath());System.out.println(文件大小字节file1.length());System.out.println(最后修改时间newDate(file1.lastModified()));// 创建文件FilenewFilenewFile(D:/test/newfile.txt);if(!newFile.exists()){booleancreatednewFile.createNewFile();System.out.println(文件创建(created?成功:失败));}// 创建目录FiledirnewFile(D:/test/subdir);dir.mkdir();// 创建单级目录dir.mkdirs();// 创建多级目录父目录不存在也会创建// 遍历目录FiletestDirnewFile(D:/test);String[]fileNamestestDir.list();// 返回文件名数组File[]filestestDir.listFiles();// 返回File对象数组if(files!null){for(Filef:files){Stringtypef.isDirectory()?[目录]:[文件];System.out.println(type f.getName());}}// 删除文件或空目录newFile.delete();}}File类的核心方法总结exists()— 判断文件或目录是否存在createNewFile()— 创建新文件mkdir()/mkdirs()— 创建目录delete()— 删除文件或空目录list()/listFiles()— 列出目录内容getName()/getPath()/getAbsolutePath()— 获取路径信息三、字节流InputStream与OutputStream3.1 字节输入流 InputStreamInputStream是字节输入流的抽象基类定义了读取字节数据的基本方法。作为整个字节输入体系的顶层抽象它提供了三个层次的读取能力单个字节读取、批量字节数组读取、以及指定偏移量的读取。实际开发中建议使用后两种因为批量读取可以减少系统调用次数。publicabstractclassInputStream{publicabstractintread()throwsIOException;// 读取单个字节publicintread(byte[]b)throwsIOException;// 读取到字节数组publicintread(byte[]b,intoff,intlen);// 读取指定长度publicvoidclose()throwsIOException;// 关闭流}开发中常见的困惑read()返回int类型而不是byte类型这是为什么因为byte的取值范围是-128到127而read()需要用-1来表示已读到末尾。如果返回byte就没法区分读到了值为255的字节和流结束了。使用int0到255返回-1就能完美解决这个二义性问题。FileInputStream是InputStream的常用子类用于从文件中读取字节数据importjava.io.FileInputStream;importjava.io.IOException;publicclassFileInputStreamDemo{publicstaticvoidmain(String[]args){FileInputStreamfisnull;try{// 创建文件输入流fisnewFileInputStream(D:/test/hello.txt);// 方式一逐字节读取intdata;while((datafis.read())!-1){System.out.print((char)data);}// 方式二批量读取到字节数组效率更高byte[]buffernewbyte[1024];intlen;while((lenfis.read(buffer))!-1){StringcontentnewString(buffer,0,len);System.out.print(content);}}catch(IOExceptione){e.printStackTrace();}finally{// 必须在finally中关闭流if(fis!null){try{fis.close();}catch(IOExceptione){e.printStackTrace();}}}}}3.2 字节输出流 OutputStreamOutputStream是字节输出流的抽象基类importjava.io.FileOutputStream;importjava.io.IOException;publicclassFileOutputStreamDemo{publicstaticvoidmain(String[]args){FileOutputStreamfosnull;try{// true表示追加模式不传或false表示覆盖模式fosnewFileOutputStream(D:/test/output.txt,true);// 写入字节数据StringtextHello, Java IO!\r\n;fos.write(text.getBytes());// 写入字节数组fos.write(A);// 写入单个字节// 强制刷出缓冲区到磁盘fos.flush();System.out.println(写入成功);}catch(IOExceptione){e.printStackTrace();}finally{if(fos!null){try{fos.close();}catch(IOExceptione){e.printStackTrace();}}}}}3.3 文件拷贝示例结合输入流和输出流实现文件拷贝importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;publicclassFileCopyDemo{publicstaticvoidcopyFile(StringsrcPath,StringdestPath){try(FileInputStreamfisnewFileInputStream(srcPath);FileOutputStreamfosnewFileOutputStream(destPath)){byte[]buffernewbyte[4096];intlen;while((lenfis.read(buffer))!-1){fos.write(buffer,0,len);}System.out.println(文件拷贝完成);}catch(IOExceptione){e.printStackTrace();}}publicstaticvoidmain(String[]args){copyFile(D:/test/source.jpg,D:/test/dest.jpg);}}小提示上面使用了try-with-resources语法Java 7实现了流的自动关闭无需手动编写finally块。四、字符流Reader与Writer字符流用于处理文本数据自动处理字符编码问题。4.1 FileReader与FileWriterimportjava.io.FileReader;importjava.io.FileWriter;importjava.io.IOException;publicclassFileReaderWriterDemo{publicstaticvoidmain(String[]args){// 写入文本文件try(FileWriterfwnewFileWriter(D:/test/poem.txt)){fw.write(床前明月光\r\n);fw.write(疑是地上霜。\r\n);fw.write(举头望明月\r\n);fw.write(低头思故乡。\r\n);System.out.println(文件写入成功);}catch(IOExceptione){e.printStackTrace();}// 读取文本文件try(FileReaderfrnewFileReader(D:/test/poem.txt)){char[]buffernewchar[1024];intlen;while((lenfr.read(buffer))!-1){System.out.print(newString(buffer,0,len));}}catch(IOExceptione){e.printStackTrace();}}}4.2 字节流与字符流的桥接当需要处理字节流但想要字符流特性时可以使用InputStreamReader和OutputStreamWriter这两个转换流将在后续文章详细讲解。五、try-with-resources 自动关闭资源Java 7引入的try-with-resources机制极大简化了流的关闭操作。任何实现了java.lang.AutoCloseable接口的类都可以使用此语法// 传统写法繁琐FileInputStreamfisnull;try{fisnewFileInputStream(test.txt);// ... 处理数据}finally{if(fis!null)fis.close();}// try-with-resources 写法简洁try(FileInputStreamfisnewFileInputStream(test.txt);FileOutputStreamfosnewFileOutputStream(out.txt)){// ... 处理数据资源会自动关闭}catch(IOExceptione){e.printStackTrace();}执行顺序后声明的资源先关闭先声明的资源后关闭类似栈的先进后出。六、IO流使用的最佳实践以下几条实践原则是在实际开发中被反复验证过的经验总结选择合适的流类型二进制数据用字节流Stream文本数据用字符流Reader/Writer。这里的二进制包括但不限于图片、视频、压缩包、序列化对象等任何非纯文本格式。如果用字符流处理二进制数据编码转换会破坏原始字节。始终关闭流使用try-with-resources自动管理资源。未关闭的流不仅造成内存泄漏还可能导致文件句柄耗尽——在Linux系统上每个进程可打开的文件数有上限满后无法再打开任何文件。使用缓冲区使用byte[]或char[]缓冲区批量读写显著提升性能。一个4KB的缓冲区就能将读写效率提升数十倍因为系统调用的开销远大于内存复制。编码问题读写文本时注意指定字符编码避免乱码。这是跨平台部署时最常踩的坑——Windows默认GBKLinux默认UTF-8不显式指定编码就会在上线后出现乱码。路径处理使用File.separator代替硬编码的路径分隔符增强跨平台兼容性。或者在Java 7中使用Paths.get()统一处理。总结本文详细介绍了Java IO流体系的核心概念File类用于表示文件和目录的元信息是操作文件系统的入口字节流InputStream/OutputStream处理二进制数据适合图片、视频等文件字符流Reader/Writer处理文本数据内置字符编码支持try-with-resources自动关闭资源的现代写法推荐在所有IO操作中使用掌握IO流体系是Java开发的基础技能后续文章将继续深入讲解缓冲流、转换流以及NIO等高级IO技术。✅ 亮点总结IO流按流向输入/输出和处理单位字节/字符两个维度的二维分类体系形成四象限架构File类作为文件系统入口封装了创建/删除/遍历/属性读取等完整的元信息操作字节流FileInputStream/FileOutputStream处理二进制数据字符流FileReader/FileWriter处理文本并内置编码文件拷贝的完整实现4KB缓冲区批量读写 try-with-resources自动关闭兼顾性能与安全性try-with-resources语法Java 7的资源自动管理机制后声明先关闭的栈式释放顺序适用场景配置文件读取与解析如properties、json、yaml等格式文件的加载日志文件的批量写入与按日期归档组合File类创建目录和字符流写入内容文件上传下载功能的底层实现字节流处理任意格式、字符流处理文本内容扩展方向深入学习缓冲流BufferedInputStream/BufferedReader的性能优化原理与字符编码转换研究Apache Commons IO和Google Guava的高效IO工具类封装推荐阅读22_Java缓冲流与转换流下一篇Java缓冲流与转换流

相关新闻

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

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

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

阅读更多
双AI驱动:借助快马平台的AI能力,智能生成mmrotate文档旋转文本框检测项目代码
2026/6/13 6:30:20

双AI驱动:借助快马平台的AI能力,智能生成mmrotate文档旋转文本框检测项目代码

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 你是一个AI编程助手,请根据以下自然语言描述,生成一个完整且可运行的mmrotate项目代码。描述如下:我想创建一个能够识别和定位文档图片中所有倾…

阅读更多
避开Halcon模板匹配的坑:为什么你的.shm文件读取后匹配效果变差了?
2026/6/12 19:25:00

避开Halcon模板匹配的坑:为什么你的.shm文件读取后匹配效果变差了?

为什么你的Halcon模板匹配效果变差了?5个隐藏陷阱与解决方案当你信心满满地将保存好的.shm文件加载到新项目中,却发现匹配效果大不如前——分数骤降、目标漏检、误匹配频发。这不是个例,而是大多数Halcon开发者都会遇到的"模板迁移综合征…

阅读更多
MuleSoft驱动的企业级AI编排:LLM与业务系统深度集成实践
2026/6/14 0:57:30

MuleSoft驱动的企业级AI编排:LLM与业务系统深度集成实践

1. 项目概述:当企业级集成平台遇上大语言模型“AI Orchestration in Action: How MuleSoft and LLMs Fuel the Future of Enterprise AI”——这个标题不是一句空泛的营销口号,而是我在过去18个月里亲手搭建、上线并持续迭代的三个核心生产系统的统一命名…

阅读更多
数据反熵自动化:构建可自愈的数据一致性系统
2026/6/14 0:57:30

数据反熵自动化:构建可自愈的数据一致性系统

1. 项目概述:这不是“数据修复”,而是让系统自己学会“纠错”和“自愈”“Data Anti-Entropy Automation”——这个标题乍看像学术论文里的术语,但在我过去十年带团队做数据平台、治理中台和实时数仓的实战里,它其实对应着一个每天…

阅读更多
Anthropic提示层归零:模型即协议的工程实践
2026/6/14 0:57:30

Anthropic提示层归零:模型即协议的工程实践

1. 项目概述:这不是一次普通更新,而是一次架构级“蒸发”“Anthropic Just Shipped the Layer That’s Already Going to Zero”——这个标题一出来,我正在调试一个Claude调用链的终端前停了三秒。不是因为震惊,而是因为熟悉&…

阅读更多
Prompt Engineering:重构人机协作的工程化方法论
2026/6/14 0:57:30

Prompt Engineering:重构人机协作的工程化方法论

1. 项目概述:这不是“写提示词”,而是重构人机协作的底层逻辑“Prompt Engineering”这个词,这两年被讲得太多,也太轻飘。很多人把它理解成“给AI发指令的技巧”,甚至简化为“多加几个形容词”“换种说法再试一次”。我…

阅读更多
别再只用BERT了!用Transformers库的AutoModel,5分钟搞定文本相似度计算(附代码对比)
2026/6/14 0:57:30

别再只用BERT了!用Transformers库的AutoModel,5分钟搞定文本相似度计算(附代码对比)

超越BERT:用Transformers库高效实现文本相似度计算的三种实战方案在自然语言处理领域,文本相似度计算是信息检索、问答系统和推荐系统等应用的核心技术。传统方法如TF-IDF或Word2Vec已逐渐被基于Transformer的预训练模型所取代。Hugging Face的Transform…

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

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

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

阅读更多
别再只用BERT了!用Transformers库的AutoModel,5分钟搞定文本相似度计算(附代码对比)
2026/6/14 0:57:30

别再只用BERT了!用Transformers库的AutoModel,5分钟搞定文本相似度计算(附代码对比)

超越BERT:用Transformers库高效实现文本相似度计算的三种实战方案在自然语言处理领域,文本相似度计算是信息检索、问答系统和推荐系统等应用的核心技术。传统方法如TF-IDF或Word2Vec已逐渐被基于Transformer的预训练模型所取代。Hugging Face的Transform…

阅读更多
Prompt Engineering:重构人机协作的工程化方法论
2026/6/14 0:57:30

Prompt Engineering:重构人机协作的工程化方法论

1. 项目概述:这不是“写提示词”,而是重构人机协作的底层逻辑“Prompt Engineering”这个词,这两年被讲得太多,也太轻飘。很多人把它理解成“给AI发指令的技巧”,甚至简化为“多加几个形容词”“换种说法再试一次”。我…

阅读更多
Anthropic提示层归零:模型即协议的工程实践
2026/6/14 0:57:30

Anthropic提示层归零:模型即协议的工程实践

1. 项目概述:这不是一次普通更新,而是一次架构级“蒸发”“Anthropic Just Shipped the Layer That’s Already Going to Zero”——这个标题一出来,我正在调试一个Claude调用链的终端前停了三秒。不是因为震惊,而是因为熟悉&…

阅读更多
别再只用BERT了!用Transformers库的AutoModel,5分钟搞定文本相似度计算(附代码对比)
2026/6/14 0:57:30

别再只用BERT了!用Transformers库的AutoModel,5分钟搞定文本相似度计算(附代码对比)

超越BERT:用Transformers库高效实现文本相似度计算的三种实战方案在自然语言处理领域,文本相似度计算是信息检索、问答系统和推荐系统等应用的核心技术。传统方法如TF-IDF或Word2Vec已逐渐被基于Transformer的预训练模型所取代。Hugging Face的Transform…

阅读更多
Prompt Engineering:重构人机协作的工程化方法论
2026/6/14 0:57:30

Prompt Engineering:重构人机协作的工程化方法论

1. 项目概述:这不是“写提示词”,而是重构人机协作的底层逻辑“Prompt Engineering”这个词,这两年被讲得太多,也太轻飘。很多人把它理解成“给AI发指令的技巧”,甚至简化为“多加几个形容词”“换种说法再试一次”。我…

阅读更多
Anthropic提示层归零:模型即协议的工程实践
2026/6/14 0:57:30

Anthropic提示层归零:模型即协议的工程实践

1. 项目概述:这不是一次普通更新,而是一次架构级“蒸发”“Anthropic Just Shipped the Layer That’s Already Going to Zero”——这个标题一出来,我正在调试一个Claude调用链的终端前停了三秒。不是因为震惊,而是因为熟悉&…

阅读更多
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是一个…

阅读更多