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

【Java基础|第三十二篇】增强流、缓冲流、标准流、转换流

(九)File流与IO流

3、IO流(增强流部分)
(1)节点流与增强流:
        概述:

                IO流按照功能划分为节点流和增强流

        节点流:        

                最基本的IO流, 直接与数据源或目标进行交互,但缺乏一些高级功能。

                它们提供了最底层的读写功能,可以直接读取或写入底层数据源或目标,如文件、网络连接等。

                节点流只能提供最基本的读写功能,实际开发中我们很少单独使用它们,也解决复杂IO功能。

                上面我们学习的所有流都是节点流:

                        FileInputStream 和 FileOutputStream :用于读取和写入文件的字节流。

                        FileReader 和 FileWriter :用于读取和写入文件的字符流

                        ByteArrayInputStream 和 ByteArrayOutputStream :用于读取和写入字节数组的 

        增强流:

                其在节点流的基础上提供了额外的功能和操作

                增强流提供了更高级的操作和便利性,使得 IO 操作更加方便、高效和灵活

                增强流不可以独立使用,必须通过装饰器模式包装节点流,可以在节点流上添加缓冲、字符编码转换、对象序列化等功能

                常见增强流:缓冲流、标准流、转换流、对象流,数据流,随机访问流等

(2)缓冲流:
<1>缓冲思想:

        在 Java I/O 流中,缓冲思想是一种常见的优化技术,用于提高读取和写入数据的效率。它通过在内存中引入缓冲区(Buffer)来减少实际的 I/O 操作次数,从而提高数据传输的效率。

        缓冲思想的基本原理是将数据暂时存储在内存中的缓冲区中,然后按照一定的块大小进行读取或写入操作。相比于直接对磁盘或网络进行读写操作,使用缓冲区可以减少频繁的 I/O 操作,从而提高效率。

<2>缓冲流概述:

         缓冲流(Buffered Streams)也叫高效流,是一种非常有用的增强流,提供了缓冲功能,可以提高 IO 操作的效率。

        缓冲流它们通过在内存中创建一个缓冲区,将数据暂时存储在缓冲区中,然后批量读取或写入数据,减少了频繁的磁盘或网络访问,从而提高了读写的性能。 

        常见的缓冲流:bufferedInputStream、bufferedOutputStream 缓冲字节输入输出流

                                  bufferedReader,bufferedWriter  缓冲字符输入输出流

内存字节流与缓冲流的区别:

        内存字节流中,内存中的字节数组扮演的是数据的目的地,数据源;他解决得是数据的临时存储,主要用于需要短暂存储的数据,不用放在硬盘中,提高了速率,数据随流对象存在。

        缓冲流:内存中的缓冲区扮演一个中间角色,作为流的增强器(从输入流拿去一部分数据到缓存区,等缓存区满之后一次性传给程序,或者从输出流拿取一部分数据放在缓存区,等到缓存区满之后一次性传给输入流,减少了输入流与输出流与硬盘之间的频繁操作,提高了传输速率)。

        总而言之,内存字节流内存中的字节数组本质是数据容器,替代了硬盘或者是其他外部设备的存储功能。而缓冲流本质是性能优化的中间层,不存储最终的数据,只在程序与外部设备之间增加缓冲层。

<3>缓冲字节流:

①缓冲字节输入流:bufferedInputStream 

         继承四大父类InputStream

class BufferedInputStream extends FilterInputStream {//省略...//默认缓冲区大小8192字节private static int DEFAULT_BUFFER_SIZE = 8192;//字节数组protected volatile byte buf[];//缓冲区最大字节数private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;//缓冲输入流,又称为包装流,使用时需要传入基本输入字节流对象public BufferedInputStream(InputStream in);//size,代表设置读取缓冲大小public BufferedInputStream(InputStream in, int size);
}

         主要方法:所继承的是文件字节输入流的read方法,依旧是3种

         构造方法:由上图部分源码可知,构造方法有两个,注意参数是字节节点流对象,必须是字节输入流父类对象或者是子类的对象。

 ②缓冲字节输出流:bufferedOutputStream

        继承四大父类:OutputStream       

public class BufferedOutputStream extends FilterOutputStream {//省略...protected byte buf[];//使用时需要传入基本输出字节流对象,默认缓冲区大小8192字节public BufferedOutputStream(OutputStream out) {this(out, 8192);}//size,代表设置写入缓冲大小public BufferedOutputStream(OutputStream out, int size);
}

        主要方法:所继承的是文件字节输出流的write方法,依旧是3种

        构造方法:由上图部分源码可知,构造方法有两个,注意参数是字节节点流对象,必须是字节输入流父类对象或者是子类的对象。

案例展示:缓冲流拷贝内容与节点流拷贝内容的比较

public class Test026_Buffered {public static void main(String[] args) throws Exception {//1.创建流对象FileInputStream fis = new FileInputStream("D:\\test\\1.png");FileOutputStream fos = new FileOutputStream("D:\\test\\2.png");//2.借助节点流流 进行 逐行读取long start = System.currentTimeMillis();int data;while((data = fis.read()) != -1) {fos.write(data);}long end = System.currentTimeMillis();System.out.println("拷贝完成,拷贝时长: " + (end - start) + "ms");//3.只需要关闭 最后的增强流对象即可fos.close();fis.close();}
}
//输出结果:文件大小5M左右,注意每次运行结果稍微不同
拷贝完成,拷贝时长: 36410ms
public static void main(String[] args) throws Exception {//1.创建缓冲流FileInputStream fis = new FileInputStream("D:\\test\\1.png");// 注意:缓冲流是增强流,其底层借助节点流实现功能,所以创建时须传入一个节点流对象BufferedInputStream bis = new BufferedInputStream(fis);BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\test\\2.png"));//2.借助缓冲流 进行 逐行读取long start = System.currentTimeMillis();byte[] buff = new byte[1024];int len;while((len = bis.read(buff)) != -1) {bos.write(buff, 0, len);//刷新缓冲流bos.flush();}long end = System.currentTimeMillis();System.out.println("拷贝完成,拷贝时长: " + (end - start) + "ms");//3.只需要关闭 最后的增强流对象即可bos.close();bis.close();
}
//输出结果:文件大小5M左右,注意每次运行结果稍微不同
拷贝完成,拷贝时长: 35ms

从两个的对比中,可以明显看到缓冲流提高了速率。

<4>缓冲字符流:

缓冲字符输入流:bufferedeader

        继承四大父类Reader

public class BufferedReader extends Reader {//省略...//基础流private Reader in;//字符数组private char cb[];//默认缓冲区大小private static int defaultCharBufferSize = 8192;//缓冲输入流,又称为包装流,使用时需要传入基本输入字符流对象public BufferedReader(Reader in);//size,代表设置读取缓冲大小public BufferedReader(Reader in, int size);//新增功能:逐行读取数据//如果没有下一行数据了,返回`null`public String readLine() throws IOException;
}

        构造方法:由上图部分源码可知,构造方法有两个,注意参数是节点流对象,必须是字符输入流对象或者是它的子类对象

        主要方法:String readline():一次性读取一整行文本

                                缓冲字符输入流对象调用,返回所获取到的字符串,无参

                          Reader父类中有方法:

                                boolean ready()返回true表示当前流还可以继续读取数据

                                                              返回false表示可能要结束或需要等待数据

                                                              用于读取数据是检验是否还有数据可读

                           其他的read方法与文件字符输入流一样。

缓冲字符输出流:bufferedWriter

        继承四大父类Writer

public class BufferedWriter extends Writer {//省略...//基础流private Writer out;//字符数组private char cb[];//默认缓冲区大小private static int defaultCharBufferSize = 8192;//缓冲输出流,又称为包装流,使用时需要传入基本输出字符流对象public BufferedWriter(Writer out);//size,代表设置写入缓冲大小public BufferedWriter(Writer out, int size);//新增功能:写入一个换行符,windows、linux等都适用public void newLine() throws IOException;
}

        构造方法:由上图部分源码可知,构造方法有两个,注意参数是节点流对象,必须是字符输出流对象或者是它的子类对象

        主要方法:void newline() 根据当前系统输出一行后插入换行符

                          其他的写入方法与文件字符输出流一致(Write(String s),write(int c),writer(char[] c));

案例展示:

public class Test026_BufferedChar {public static void main(String[] args) throws Exception {//1.BufferedReader br = new BufferedReader(new FileReader("src/dir/a.txt"));BufferedWriter bw = new BufferedWriter(new FileWriter("src/dir/b.txt"));//2.逐行读取 输出 最后拷贝String line;//读取整行数据 不包含 换行符while((line = br.readLine()) != null) {//输出读取整行数据System.out.println("read: " + line);//将读取的整行数据 写入b.txtbw.write(line);//额外写换行符: 如果后续没有数据了,则不要再写换行符// ready()返回false可理解为:马上要读取到文件尾if(br.ready())bw.newLine();}//3.bw.close();br.close();}
}
(3)标准流:
<1>概述:

        标准流(Standard Streams)是指三个预定义的流对象,用于处理标准输入、标准输出和标准错误。这些标准流在 Java 中是自动创建的,无需显式地打开或关闭。

<2>标准输入流:System.in

        它是一个字节流(InputStream),用于从标准输入设备(通常是键盘)读取数据。可以使用 Scanner 或 BufferedReader 等类来读取标准输入流的数据。

        主要用法:一般借助Scanner与bufferedReader

                Scanner sc = new Scanner(System.in);

                bufferedReader r = new BufferedReader(System.in);

                String a = r.readline();  一行一行读     

        默认从控制台写入,如果想要将文件中的写入,可以使用System.setIn(InputStream is)          

<3>标准输出流:

        它是一个字节流(PrintStream),用于向标准输出设备(通常是控制台)输出数据。可以使用 System.out.println() 或 System.out.print()等方法来输出数据到标准输出流。

        默认输出到控制台,如果想输出到文件中,可以使用System.setOut(printStream ps) ;

<4>标准错误流: 

        用于向标准错误设备(通常是控制台)输出错误信息。与标准输出流相比,标准错误流通常用于输出错误、警告或异常信息。

        默认输出到控制台,如果想输出到文件中,可以使用System.setErr(PrintStream ps)

  PrintStream:一个增强流

                        提供了一系列print与println方法,可以输出各种数据类型得值,并自动转化为字符创形式。

                        特殊之处:构造方法可以直接传路径,可以不传流对象     

http://www.xdnf.cn/news/1434079.html

相关文章:

  • 【Qt】bug排查笔记——QMetaObject::invokeMethod: No such method
  • Telnet 原理与配置
  • Deepin25安装mysql8.4.5
  • 【鸿蒙面试题-6】LazyForEach 懒加载
  • MQTT报文的数据结构
  • LeeCode104. 二叉树的最大深度,LeeCode111. 二叉树的最小深度
  • 动手学深度学习
  • 2025年IT行业女性职业发展证书选择指南
  • 企业微信怎么用能高效获客?拆解体检品牌如何实现私域营收提升
  • ReactAgent接入MCP服务工具
  • WMT2014:机器翻译领域的“奥林匹克盛会“
  • 【Unity开发】丧尸围城项目实现总结
  • 双八无碳小车cad+三维图+仿真+设计说明书
  • 快速入门Vue3——基础语法
  • SpringBoot RestTemplate 设置http请求连接池
  • 一个真正跨平台可用的免费PDF解决方案
  • 同步整流芯片为何容易受损?如何应对呢?
  • 第十七讲:编译链接与函数栈帧
  • 电机控制(二)-控制理论基础
  • 互联网向无线通信发展的关键历史时期
  • 睿思芯科正式加入龙蜥社区,携手共建 RISC-V 服务器生态新标杆
  • thinkphp6通过workerman使用websocket
  • ArkUI核心功能组件使用(一)
  • 强化学习PPO/DDPG算法学习记录
  • 01 - 网页和web标准
  • Spring Boot数据脱敏方案
  • java-设计模式-5-创建型模式-建造
  • quant, 量化交易,合约,期货心得,短线交易心得
  • Vue3 + GSAP 动画库完全指南:从入门到精通,打造专业级网页动画
  • 人工智能与强化学习:使用OpenAI Gym进行项目开发