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

【自用】JavaSE--IO流(二)--缓冲流、转换流、打印流、数据流、序列化流、IO框架

缓冲流

缓冲流的作用:对原始流进行包装,提升原始流读写数据的性能

字节缓冲流

也可以自定义缓冲池的大小,写法示例: InputStream is_buffer = new BufferedInputStream(is, 8192*2);

示例:

代码:

public class test {public static void main(String[] args){try (InputStream is = new FileInputStream("D:\\Desktop\\备份\\萌萌香.png");OutputStream os = new FileOutputStream("D:\\Desktop\\test\\萌萌香.png");//将两个原始流封装成缓冲流InputStream is_buffer = new BufferedInputStream(is, 8192*2);//也可以自己定义缓冲池大小OutputStream os_buffer = new BufferedOutputStream(os, 8192*2);){byte[] buffer = new byte[1024];//一次读1024B,即 1KBint len; //每次读取到的字节数while( (len=is_buffer.read(buffer))!=-1 ){os_buffer.write(buffer,0,len);}System.out.println("复制成功!");} catch (Exception e) {e.printStackTrace();}}
}

字符缓冲流

字符缓冲输入流

原理与字节缓冲流基本一致,不过是单位从字节变成字符罢了

读取的操作与原始流读取的操作完全一致,就是多了一步将原始流包装成缓冲流的步骤

readline案例(readline是BufferedReader的特有方法,因此不能采用多态的写法):

字符缓冲输出流

原理与字节缓冲输出流类似

示例(执行3次):

案例

将乱序的句子排完序且复制到新文件中去

注意: .   $  |   *   等转义字符,必须得加 \\      用\表示\是转义字符

代码(自己写版):

public class copy_Demo {public static void main(String[] args) {try (BufferedReader brd = new BufferedReader(new FileReader("File-IO\\src\\com\\CJ\\unsorted"));BufferedWriter bwr = new BufferedWriter(new FileWriter("File-IO\\src\\com\\CJ\\sorted"))){//把所有句子装进集合List<String> sentences = new ArrayList<>();String line;while( (line= brd.readLine())!=null ){sentences.add(line);}//排序Collections.sort(sentences, new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {String[] split1 = o1.split("\\.");String[] split2 = o2.split("\\.");return Integer.valueOf(split1[0])-Integer.valueOf(split2[0]);}});//去掉序号for(int i=0;i<sentences.size();i++){String[] s = sentences.get(i).split("\\.");sentences.set(i,s[1]);}//复制到新文件去for(int i=0;i<sentences.size();i++){bwr.write(sentences.get(i));bwr.newLine();}System.out.println("已排序完且复制到新文件中!");} catch (Exception e) {e.printStackTrace();}}
}

代码(优化版):

public class copy_Demo {public static void main(String[] args) {try (BufferedReader brd = new BufferedReader(new FileReader("File-IO\\src\\com\\CJ\\unsorted"));BufferedWriter bwr = new BufferedWriter(new FileWriter("File-IO\\src\\com\\CJ\\sorted"))){//把所有句子装进集合List<String> sentences = new ArrayList<>();String line;while( (line= brd.readLine())!=null ) sentences.add(line);//排序Collections.sort(sentences, (o1, o2) -> Integer.valueOf(o1.substring(0,o1.indexOf('.')))-Integer.valueOf(o2.substring(0,o2.indexOf('.'))));//去掉序号for(int i=0;i<sentences.size();i++){String s = sentences.get(i);s = s.substring(s.indexOf('.')+1);sentences.set(i,s);}//复制到新文件去for(String s : sentences){bwr.write(s);bwr.newLine();}System.out.println("已排序完且复制到新文件中!");} catch (Exception e) {e.printStackTrace();}}
}

性能分析

可以通过 System.currentTimeMillis()    获取系统时间,只要在程序执行最开始和最后分别获取时间(单位为毫秒),再相减就能得知程序运行时间

通过这种方法分别测试原始流和缓冲流就能得知缓冲流的速度明显快很多

采用的字节数组越大,性能越强,但当字节数组大到一定程度时对性能的提升微乎其微,但却消耗了大量的时间,理解为用空间换时间了,因此还是需要选取一个适合应用场景的字节数组大小

转换流

可能出现的问题:编码解码不一致导致读取的文件出现乱码

比如在java中使用UTF-8进行编码,然后想要读取一个文件,但是这个文件是GBK编码的,此时执行程序就会发生乱码

解决办法 ---> 转换流

字符输入转换流

示例(这里的test.txt采用GBK编码):

如果不指定转换流的编码,则使用默认编码,我这里java的编码为UTF-8,会出现乱码,如下图

字符输出转换流

和上面差不多,也是指定一个字符集编码,之后输出都是按照指定的字符集编码的

示例:

打印流

可以实现更方便、更高效的打印数据出去,能实现打印啥出去就是啥出去(打印97就是97,不会变成a)

PrintStream

示例:

PrintWriter

与PrintStream几乎一样,PrintWriter继承于字符输出流,因此PrintWriter的write方法支持写的数据类型更多更多

扩展:如何追加数据

由于打印流是高级流,并不支持直接在文件中追加数据,但可以通过 封装低级的支持追加数据的流 从而实现追加数据,示例如下:

案例:输出语句的重定向

平时使用sout输出的数据会打印到控制台,而打印流可以改变输出的位置,比如输出到文件里去,这种操作就称为输出语句的重定向

使用 System.setOut(打印流名);  修改系统默认的打印流,系统默认的打印流就是输出到控制台的

示例:

数据流

数据输出流

同时将数据类型与数据类型存在文件中,不是乱码,是把数据和其类型一并存进去了(这种数据输出流,把数据存到文件里去,不是为了给人阅读的,是为了存进去,方便下次又能读出来)

写的数据和读的数据顺序要一样,示例如下,与上面存入的一致

序列化流

对象序列化:把java对象写到文件中去

对象反序列化:把文件中的对象读出来

序列化流就是用来写对象或读对象的

对象字节输入流

如果对象需要序列化,则必须要实现序列化接口Serializable 

序列化接口相当于是一个标记,它是给jvm虚拟机程序看的。这个对象只有实现虚拟实现序列化接口,jvm才能够允许这个对象按照特定的方式存入到文件中去。

示例:

对象字节输出流

反序列化操作时并不知道具体的对象类型是什么,因此返回了个Object类型,自己强转即可

示例:

扩展1:有不想序列化的变量怎么办

在对象中不想序列化的变量前加上transient修饰符,这样该变量就不会参与序列化

扩展2:如何一次序列化多个对象

把对象放到ArrayList集合里,直接对ArrayList进行序列化

IO框架

怎么理解,一个框架里有很多类,类里面有很多方法,这些方法就是一些经常会用到的操作,比如复制、粘贴、删除等。就是一些高手造好了轮子给大家拿来用

一般这些框架都是第三方开发的,因此想要使用就必须要先下载过来才能使用

Commons-io框架

可以直接通过文件复制,也可以通过流来复制

两个常用类:FileUtils、IOUtils,对应常用方法如下图:

如何导入框架

lib翻译为库,基本上就是拿来放框架的

补充

java官方在后来的版本更新中也提供了一个 Files类,支持一行代码完成复制等操作

但commons-io还是更强大一些

http://www.dtcms.com/a/324634.html

相关文章:

  • 硬件开发_基于STM32单片机的智能电梯系统
  • 【RocketMQ 生产者和消费者】- ConsumeMessageConcurrentlyService 并发消费消息
  • 自然语言处理入门路线-实践篇
  • AutoCAD 2026 的主要功能
  • 如何选择适合自己电商业务的 API?​
  • 解决RuoYi-Cloud项目ruoyi-system模块启动失败问题以及Naco容器部署问题
  • 【21】OpenCV C++实战篇——OpenCV C++案例实战二十七《角度测量》
  • SpringAI智能航空助手实战<Demo>
  • 《算法导论》第 17 章 - 摊还分析
  • XGBoost 与 GBDT 的比较:改进与性能提升
  • MATLAB绘制水的蒸汽压曲线(Antoine方程)
  • GitHub上为什么采用Gradle编译要多于Maven
  • DBSACN算法的一些应用
  • 【算法】图的 深度优先搜索(DFS)与 广度优先搜索(BFS)
  • Stream流应用
  • 学习分库分表的前置知识:高可用系统架构理论与实践
  • Java进阶之单列集合Set接口下的通用方法
  • Design Compiler:布图规划探索(ICC II)
  • LwIP的内存管理(1)
  • 密码学RSA取flag
  • 动态工作流:目标结构源自表
  • GeoJSON 介绍
  • 大模型时代的机器人研究趋势:从多模态融合到高效迁移
  • 【C++/STL】list模拟实现和迭代器失效问题
  • Spring Boot配置文件加密详解
  • 6.AD环境中的安全威胁与防护措施全性
  • java报错“ NoSuchMethodError:com.test.Service.doRoomList(Ljava/lang/String;)V解决方案
  • 红黑树及其简单实现
  • XGBoost参数说明和详解
  • Suno API V5 全面升级——多语言接入,开启 AI 音乐创作新时代