当前位置: 首页 > news >正文

【JavaSE全面教学】Java IO流与文件操作Day14(2026年)

写在前面这是JavaSE系列的第14篇。IO流是Java中处理文件读写和网络通信的基础。很多初学者觉得IO流很混乱——什么字节流、字符流、缓冲流搞不清该用哪个。今天我把IO流体系彻底梳理一遍。文章目录一、IO流概述1.1 什么是IO流1.2 IO流的分类二、字节流处理所有文件2.1 FileInputStream字节输入流2.2 FileOutputStream字节输出流2.3 文件复制三、字符流处理文本文件3.1 FileReader字符输入流3.2 FileWriter字符输出流3.3 字节流 vs 字符流四、缓冲流提高IO效率4.1 BufferedReader和BufferedWriter4.2 BufferedInputStream和BufferedOutputStream4.3 缓冲流为什么更快4.4 文件复制的最佳写法五、转换流字节流和字符流的桥梁5.1 InputStreamReader5.2 OutputStreamWriter六、对象序列化6.1 什么是序列化6.2 Serializable接口6.3 序列化和反序列化七、Properties配置文件读写八、NIO简介Java 78.1 Files类Java 78.2 NIO vs IO参考资料九、面试高频考点考点1字节流和字符流的区别考点2缓冲流为什么更快考点3序列化的注意事项十、总结一、IO流概述1.1 什么是IO流实际场景你每天用到的操作——读取配置文件、上传下载文件、日志写入、网络通信底层都是IO流。IO流Input/Output输入/输出流。用于在程序和外部资源文件、网络、内存等之间传输数据。程序 → 输出流Output → 文件 写文件 文件 → 输入流Input → 程序 读文件1.2 IO流的分类按方向分 ├── 输入流Input读数据读文件、读网络 └── 输出流Output写数据写文件、写网络 按单位分 ├── 字节流以字节为单位byte处理所有类型文件 │ ├── InputStream抽象类 │ │ ├── FileInputStream │ │ ├── BufferedInputStream │ │ └── ObjectInputStream │ └── OutputStream抽象类 │ ├── FileOutputStream │ ├── BufferedOutputStream │ └── ObjectOutputStream │ └── 字符流以字符为单位char专门处理文本文件 ├── Reader抽象类 │ ├── FileReader │ ├── BufferedReader │ └── InputStreamReader └── Writer抽象类 ├── FileWriter ├── BufferedWriter └── OutputStreamWriter 按功能分 ├── 节点流直接操作数据源FileInputStream、FileOutputStream └── 处理流包装节点流提供额外功能BufferedInputStream等二、字节流处理所有文件2.1 FileInputStream字节输入流踩坑提醒使用字节流读取文本文件时如果文件包含中文直接(char) b转换可能会出现乱码。因为中文字符占多个字节一个字节一个字节读取会截断字符。处理文本文件建议用字符流。importjava.io.FileInputStream;importjava.io.IOException;// 方式1一次读一个字节FileInputStreamfisnewFileInputStream(test.txt);intb;while((bfis.read())!-1){// -1表示文件结束System.out.print((char)b);}fis.close();// 方式2一次读一个字节数组推荐FileInputStreamfis2newFileInputStream(test.txt);byte[]buffernewbyte[1024];// 1KB缓冲区intlen;while((lenfis2.read(buffer))!-1){StringcontentnewString(buffer,0,len);System.out.print(content);}fis2.close();// 方式3读取全部字节Java 9FileInputStreamfis3newFileInputStream(test.txt);byte[]allBytesfis3.readAllBytes();StringcontentnewString(allBytes);fis3.close();2.2 FileOutputStream字节输出流踩坑提醒FileOutputStream默认会覆盖已有文件内容如果需要追加必须用new FileOutputStream(output.txt, true)。这个坑我踩过不止一次。importjava.io.FileOutputStream;// 写入字节FileOutputStreamfosnewFileOutputStream(output.txt);fos.write(Hello, World!.getBytes());fos.write(\r\n.getBytes());// 换行fos.write(Java IO流.getBytes());fos.close();// 追加模式FileOutputStreamfos2newFileOutputStream(output.txt,true);fos2.write(追加的内容.getBytes());fos2.close();// 写入字节数组byte[]data字节数组写入.getBytes();fos.write(data);2.3 文件复制// 字节流实现文件复制可以复制任何文件publicstaticvoidcopyFile(Stringsrc,Stringdest)throwsIOException{try(FileInputStreamfisnewFileInputStream(src);FileOutputStreamfosnewFileOutputStream(dest)){byte[]buffernewbyte[1024];intlen;while((lenfis.read(buffer))!-1){fos.write(buffer,0,len);}}}三、字符流处理文本文件3.1 FileReader字符输入流importjava.io.FileReader;// 一次读一个字符FileReaderfrnewFileReader(test.txt);intch;while((chfr.read())!-1){System.out.print((char)ch);}fr.close();// 一次读一个字符数组FileReaderfr2newFileReader(test.txt);char[]buffernewchar[1024];intlen;while((lenfr2.read(buffer))!-1){System.out.print(newString(buffer,0,len));}fr2.close();3.2 FileWriter字符输出流importjava.io.FileWriter;// 写入字符FileWriterfwnewFileWriter(output.txt);fw.write(Hello, World!\n);fw.write(Java字符流);fw.close();// 追加模式FileWriterfw2newFileWriter(output.txt,true);fw2.write(追加的内容);fw2.close();3.3 字节流 vs 字符流经验之谈很多新手纠结该用字节流还是字符流。记住一个原则——不确定就用字节流。字节流是万能的能处理任何文件字符流只是字节流的便捷封装专门处理文本。特性字节流字符流操作单位字节byte字符char适用场景所有文件图片、视频等文本文件编码问题需要手动处理自动处理编码效率更底层更灵活更方便基类InputStream/OutputStreamReader/Writer选择原则复制文件图片、视频等→字节流读写文本 →字符流不确定 →字节流万能四、缓冲流提高IO效率4.1 BufferedReader和BufferedWriterimportjava.io.*;// BufferedReader带缓冲区的字符输入流BufferedReaderbrnewBufferedReader(newFileReader(test.txt));// readLine()一次读一行最常用Stringline;while((linebr.readLine())!null){System.out.println(line);}br.close();// BufferedWriter带缓冲区的字符输出流BufferedWriterbwnewBufferedWriter(newFileWriter(output.txt));bw.write(第一行);bw.newLine();// 换行跨平台bw.write(第二行);bw.newLine();bw.flush();// 刷新缓冲区bw.close();4.2 BufferedInputStream和BufferedOutputStream// BufferedInputStream带缓冲区的字节输入流BufferedInputStreambisnewBufferedInputStream(newFileInputStream(test.txt));byte[]buffernewbyte[1024];intlen;while((lenbis.read(buffer))!-1){// 处理数据}bis.close();// BufferedOutputStream带缓冲区的字节输出流BufferedOutputStreambosnewBufferedOutputStream(newFileOutputStream(output.txt));bos.write(Hello.getBytes());bos.flush();// 刷新缓冲区bos.close();4.3 缓冲流为什么更快原理揭秘磁盘IO是计算机中最慢的操作之一。缓冲流的本质是用内存换速度——数据先在内存缓冲区中累积攒够一批后再一次性写入磁盘大大减少了磁盘访问次数。无缓冲每次读写都直接操作磁盘慢 有缓冲先读写内存缓冲区满了再操作磁盘快 无缓冲 程序 → 磁盘 → 程序 → 磁盘 → 程序 → 磁盘每次都访问磁盘 有缓冲 程序 → 缓冲区(内存) → 缓冲区满了 → 磁盘减少磁盘访问次数经验之谈缓冲区大小也有讲究。一般8KB8192字节是比较好的默认值和大多数文件系统的块大小匹配。太小了频繁IO太大了浪费内存。4.4 文件复制的最佳写法经验之谈这是我在项目中常用的文件复制模板。try-with-resources保证流一定关闭缓冲流保证效率8KB缓冲区是经验值。// 推荐写法try-with-resources 缓冲流publicstaticvoidcopyFile(Stringsrc,Stringdest){try(BufferedInputStreambisnewBufferedInputStream(newFileInputStream(src));BufferedOutputStreambosnewBufferedOutputStream(newFileOutputStream(dest))){byte[]buffernewbyte[8192];// 8KB缓冲区intlen;while((lenbis.read(buffer))!-1){bos.write(buffer,0,len);}}catch(IOExceptione){e.printStackTrace();}}踩坑提醒注意bos.write(buffer, 0, len)中的len参数最后一次读取时buffer可能没有填满如果写整个buffer会导致文件末尾多出垃圾数据。五、转换流字节流和字符流的桥梁5.1 InputStreamReader踩坑提醒读取文件乱码90%是编码问题。Windows默认GBKLinux/Mac默认UTF-8用InputStreamReader指定编码就能解决。// InputStreamReader字节流 → 字符流// 可以指定编码// 指定UTF-8编码读取InputStreamReaderisrnewInputStreamReader(newFileInputStream(test.txt),UTF-8);BufferedReaderbrnewBufferedReader(isr);Stringline;while((linebr.readLine())!null){System.out.println(line);}br.close();// 指定GBK编码读取InputStreamReaderisr2newInputStreamReader(newFileInputStream(gbk.txt),GBK);5.2 OutputStreamWriter// OutputStreamWriter字符流 → 字节流// 可以指定编码OutputStreamWriteroswnewOutputStreamWriter(newFileOutputStream(output.txt),UTF-8);BufferedWriterbwnewBufferedWriter(osw);bw.write(Hello, World!);bw.newLine();bw.close();六、对象序列化6.1 什么是序列化序列化把对象转换为字节序列存文件、网络传输反序列化把字节序列恢复为对象6.2 Serializable接口踩坑提醒实现Serializable接口时一定要手动指定serialVersionUID如果不指定JVM会自动生成但一旦类结构发生变化增删字段自动生成的UID就会变化导致反序列化失败。importjava.io.*;// 实现Serializable接口标记接口classStudentimplementsSerializable{privateStringname;privateintage;// 序列化版本号建议手动指定privatestaticfinallongserialVersionUID1L;// transient修饰的属性不会被序列化transientStringpassword;publicStudent(Stringname,intage,Stringpassword){this.namename;this.ageage;this.passwordpassword;}OverridepublicStringtoString(){returnStudent{namename, ageage, passwordpassword};}}6.3 序列化和反序列化// 序列化对象 → 文件StudentsnewStudent(张三,20,123456);try(ObjectOutputStreamoosnewObjectOutputStream(newFileOutputStream(student.dat))){oos.writeObject(s);System.out.println(序列化成功);}// 反序列化文件 → 对象try(ObjectInputStreamoisnewObjectInputStream(newFileInputStream(student.dat))){Students2(Student)ois.readObject();System.out.println(s2);// 输出Student{name张三, age20, passwordnull}// password是null因为被transient修饰}七、Properties配置文件读写importjava.io.*;importjava.util.Properties;// Properties专门读写.properties配置文件PropertiespropsnewProperties();// 写入配置props.setProperty(db.url,jdbc:mysql://localhost:3306/mydb);props.setProperty(db.username,root);props.setProperty(db.password,123456);try(FileWriterfwnewFileWriter(config.properties)){props.store(fw,数据库配置);// 第二个参数是注释}// 读取配置Propertiesprops2newProperties();try(FileReaderfrnewFileReader(config.properties)){props2.load(fr);}Stringurlprops2.getProperty(db.url);Stringusernameprops2.getProperty(db.username);System.out.println(url);// jdbc:mysql://localhost:3306/mydbSystem.out.println(username);// root八、NIO简介Java 78.1 Files类Java 7importjava.nio.file.*;// 创建文件Files.writeString(Path.of(test.txt),Hello, NIO!);// 读取文件StringcontentFiles.readString(Path.of(test.txt));// 复制文件Files.copy(Path.of(src.txt),Path.of(dest.txt));// 移动文件Files.move(Path.of(old.txt),Path.of(new.txt));// 删除文件Files.delete(Path.of(test.txt));// 创建目录Files.createDirectory(Path.of(mydir));Files.createDirectories(Path.of(a/b/c));// 创建多级目录// 遍历目录try(varstreamFiles.list(Path.of(.))){stream.forEach(System.out::println);}// 读取所有行ListStringlinesFiles.readAllLines(Path.of(test.txt));8.2 NIO vs IO特性IONIO模型面向流面向缓冲区阻塞阻塞IO非阻塞IO效率较低较高使用难度简单较复杂适用场景简单文件操作高并发网络编程参考资料Oracle官方文档 - IO流Baeldung - Java IO Tutorial九、面试高频考点考点1字节流和字符流的区别// 字节流以字节为单位处理所有文件// 字符流以字符为单位处理文本文件// 字符流底层也是字节流编码转换追问字符流底层是怎么处理编码的答案通过InputStreamReader/OutputStreamWriter底层使用StreamDecoder/StreamEncoder charset进行编码转换。考点2缓冲流为什么更快// 减少了磁盘IO次数// 数据先写入内存缓冲区满了再一次性写入磁盘考点3序列化的注意事项// 1. 实现Serializable接口// 2. 建议手动指定serialVersionUID// 3. transient修饰的属性不参与序列化// 4. 静态属性不参与序列化延伸serialVersionUID不写会怎样答案JVM会根据类结构自动计算一个。但如果类结构变化增删字段UID会变导致旧序列化数据无法反序列化抛出InvalidClassException。十、总结今天我们学习了✅ IO流的分类体系✅ 字节流和字符流的使用✅ 缓冲流提高效率✅ 转换流处理编码✅ 对象序列化✅ Properties读写配置文件✅ NIO简介重点记忆字节流处理所有文件字符流处理文本缓冲流减少磁盘IO次数提高效率try-with-resources自动关闭资源序列化实现Serializable接口推荐用NIO的Files类简化文件操作下一步预告Day15是本系列的最后一篇——Java多线程与并发基础。互动话题你在用IO流的时候有没有遇到过乱码问题是怎么解决的欢迎在评论区分享如果这篇文章对你有帮助欢迎点赞、收藏这是【JavaSE全面教学】系列的第14篇关注我看完整套教程本文为【JavaSE全面教学】系列第14篇持续更新中…
http://www.zskr.cn/news/1323558.html

相关文章:

  • 前端开发从入门到精通:Vue3+TypeScript实战教程
  • Perplexity实时新闻查询失效真相:Webhook劫持、缓存穿透与CDN时钟漂移三重陷阱
  • STD算法实战:用Python从零复现激光SLAM中的“稳定三角形”回环检测(附代码)
  • 从Silver Fox新变种看2026年网络钓鱼的攻防进化
  • 别再死记硬背了!用‘按权展开’法5分钟搞定二进制转十进制(C语言实战)
  • 【Perplexity编程搜索权威白皮书】:基于1786次真实编码场景测试,验证TOP3提示词组合准确率提升317%
  • 物理生物学研究报告【20260007】
  • 【无人机协同】联合优化无人机轨迹、发射功率与地面用户-MEC关联的多无人机多地面用户系统 附matlab代码✅
  • TI平台PMSM控制:带传感器与无传感器方案选型与实现详解
  • STM32单片机串口通信避坑指南:从CubeMX配置到中断回调函数编写
  • 发文首选!机器学习锂离子电池!
  • 【FDA级健康信息验证法】:Perplexity健康科普查询中识别虚假/过时内容的4层交叉验证模型
  • Perplexity酒店搜索精准度跃升92%的底层逻辑(LLM+实时库存融合架构首次解密)
  • Perplexity商标确权成功率提升至86.7%的关键:基于12,843件AI类商标数据训练的语义相似度校准模型(内测版开放)
  • Gemini Nano移动端模型裁剪内幕:Google内部benchmark未披露的3种Pruning策略对比(精度仅损0.7%)
  • 银河麒麟V10SP3-arm版本安装oracle19C数据库
  • 5分钟掌握抖音无水印批量下载:免费工具完整使用指南
  • 实时AI推理优化:如何提升模型响应速度
  • 【Perplexity开发者必藏资源】:17个被官方文档隐藏的调试技巧+3个内部状态检测命令
  • NPM全局安装OpenAI Codex CLI的3步权限配置与环境适配指南
  • vert-harmonium
  • 庆阳足金回收银手镯回收PT990铂金回收钻石戒指回收旧首饰回收高价多少钱一克同城价格查询上门上门估价闲置变现转让靠谱权威排行榜 - 检测回收中心
  • 南宁投资金条回收上门回收白银上门铂金回收旧钻石回收周边金银回收本地排名正规门店专业推荐哪家靠谱二手哪家强 - 检测回收中心
  • 广州小程序定制开发公司排行 性价比维度实测对比 - 奔跑123
  • Adams新手避坑指南:从几何点、Marker坐标系到立方体,这些基础元素你真的用对了吗?
  • [实测可用 v2.7.5] 桌面端 Open Claw 搭建流程全程图文教程
  • 从A/B测试到临床实验:避开P值陷阱的5个实战要点(含单尾/双尾选择指南)
  • Function Calling 实战指南:Tool Use 从原理到多工具编排,2026 完全手册
  • 浏览器图片格式转换终极指南:Save Image as Type让你的右键菜单更智能
  • 揭秘iOS 15-16 iCloud激活锁绕过:applera1n工具深度解析与实战指南