提升Java IO性能!探究BufferedOutputStream的奥秘

在这里插入图片描述
  咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java IO相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~

在这里插入图片描述


🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!!


文章目录

  • 前言
  • 摘要
  • BufferedOutputStream类
    • 概述
    • 常用方法
    • 源码分析
    • 优缺点
      • 优点:
      • 缺点:
    • 应用场景
    • 性能测试和分析
      • 测试代码
      • 测试代码分析
      • 测试结果
    • 小结
  • 总结
  • ☀️建议/推荐你
  • 📣关于我

前言

  在Java开发过程中,IO操作是我们必定会遇到的问题。而对于IO操作的性能问题,也是我们需要特别关注的问题。在Java中,我们可以通过使用BufferedOutputStream来提升IO操作的性能。本文将深入探讨BufferedOutputStream的奥秘,以提升Java IO性能。

摘要

本文将从以下几个方面入手,探究BufferedOutputStream的奥秘:

  1. BufferedOutputStream的概述和使用方法
  2. BufferedOutputStream的源代码解读
  3. BufferedOutputStream的性能测试和分析

  通过对BufferedOutputStream的深入研究,我们将了解到如何正确使用BufferedOutputStream来提升IO操作的性能,同时也可以更深入地了解Java IO的实现原理。

BufferedOutputStream类

概述

  BufferedOutputStream是Java中的一个IO流,它是OutputStream类的子类。与OutputStream不同的是,BufferedOutputStream提供了一种缓冲机制,能够将数据写入内存缓存区中,当缓存区达到一定大小时,才一次性写入到磁盘中。这种缓冲机制能够提高IO操作的效率。

常用方法

BufferedOutputStream有以下几个重要的方法:

  1. 构造方法:BufferedOutputStream(OutputStream out)
  2. 写入方法:void write(int b)
  3. 写入方法:void write(byte[] b, int off, int len)
  4. 刷新方法:void flush()
  5. 关闭方法:void close()

使用BufferedOutputStream的步骤如下:

  1. 创建输出流对象:BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"));
  2. 写入数据:bos.write("hello world".getBytes());
  3. 刷新数据:bos.flush();
  4. 关闭流:bos.close();

  需要注意的是,当使用BufferedOutputStream的时候,不要忘记使用flush()方法将缓存区中的数据写入磁盘中,否则数据可能不会被写入磁盘中。

源码分析

下面是BufferedOutputStream的源代码:

public class BufferedOutputStream extends FilterOutputStream {protected byte[] buf;protected int count;public BufferedOutputStream(OutputStream out) {this(out, 8192);}public BufferedOutputStream(OutputStream out, int size) {super(out);if (size <= 0) {throw new IllegalArgumentException("Buffer size <= 0");}buf = new byte[size];}public synchronized void write(int b) throws IOException {if (count >= buf.length) {flushBuffer();}buf[count++] = (byte) b;}public synchronized void write(byte[] b, int off, int len) throws IOException {if (len >= buf.length) {flushBuffer();out.write(b, off, len);return;}if (len > buf.length - count) {flushBuffer();}System.arraycopy(b, off, buf, count, len);count += len;}public synchronized void flush() throws IOException {flushBuffer();out.flush();}public void close() throws IOException {flush();out.close();}protected void flushBuffer() throws IOException {if (count > 0) {out.write(buf, 0, count);count = 0;}}
}

  从源代码中可以看出,BufferedOutputStream的实现原理就是在内部维护一个缓存区buf。当数据写入缓冲区后,如果缓冲区已满,就会调用flushBuffer()方法将缓冲区中的数据写入到磁盘中。同时,在关闭流之前,也必须调用flush()方法将缓存区中的数据写入磁盘中。

优缺点

  BufferedOutputStream 是 Java I/O 中的一个包装类,它可以提高 I/O 的性能。BufferedOutputStream 的主要作用是增加输出流的缓存。缓冲区的存在可以减少写磁盘的次数,因为数据都是先写入到内存中的缓存区中,等缓存区满了,再一次性将缓存区中的数据写入磁盘。这个过程可以提高写入磁盘的效率。

优点:

1.提高了写入磁盘的效率,缓冲数据减少了写磁盘的次数,减少了磁盘的读写次数,提高了程序的性能。

2.提供了对 I/O 操作的控制,可指定缓存区大小以及写入数据的位置。

3.可以按照字节写入数据,适用于所有类型的数据流。

4.与其他 I/O 类共同存在时,BufferedOutputStream 可以提供缓存增强功能。

缺点:

1.如果缓冲区较小,会增加读写 I/O 的次数,从而降低程序的性能。

2.如果程序写入的数据不满缓冲区大小,程序必须手动清空缓存区,否则写入的数据不会输出到文件。

应用场景

  BufferedOutputStream 适用于需要对数据流进行控制的场景,可以缓存数据减少磁盘的读写次数,提高程序的性能。在网络编程中,可以使用 BufferedOutputStream 提高传输效率,也可用于处理较大的音频、视频文件等数据流。此外,当需要在其他 I/O 类别中使用时,BufferedOutputStream 也可以提供缓存增强功能。

性能测试和分析

测试代码

为了测试BufferedOutputStream的性能,我们编写了如下测试代码:

package com.example.javase.io.bufferedOutputStream;import java.io.BufferedOutputStream;
import java.io.FileOutputStream;/*** @Author bug菌* @Date 2023-10-15 20:29*/
public class BufferedOutputStreamTest {public static void main(String[] args) throws Exception {String text = "hello world,jym!!!";int count = 1000000;long start1 = System.currentTimeMillis();FileOutputStream fos = new FileOutputStream("./template/hello.txt");for (int i = 0; i < count; i++) {fos.write(text.getBytes());}fos.close();long end1 = System.currentTimeMillis();long start2 = System.currentTimeMillis();BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("./template/hello.txt"));for (int i = 0; i < count; i++) {bos.write(text.getBytes());}bos.close();long end2 = System.currentTimeMillis();System.out.println("普通输出流耗时:" + (end1 - start1) + "ms");System.out.println("带缓存输出流耗时:" + (end2 - start2) + "ms");}
}

测试代码分析

根据如上测试代码进行分析:

  1. 导入需要的包。
  2. 创建一个字符串变量 text,并赋值为 hello world,jym!!!,创建一个整型变量 count,并赋值为 1000000。
  3. 通过 System.currentTimeMillis() 获取当前时间戳,作为开始时间 start1。
  4. 创建 FileOutputStream 对象 fos,指向文件路径为 ./template/hello.txt
  5. 使用 for 循环写入 count 次数据,每次调用 fos.write() 方法写入 text 转换为字节数组后的数据。
  6. 关闭 fos 流。
  7. 通过 System.currentTimeMillis() 获取当前时间戳,作为结束时间 end1。
  8. 通过 System.currentTimeMillis() 获取当前时间戳,作为开始时间 start2。
  9. 创建 BufferedOutputStream 对象 bos,通过构造方法传入 FileOutputStream 对象和缓存大小(默认为 8192 字节)。
  10. 使用 for 循环写入 count 次数据,每次调用 bos.write() 方法写入 text 转换为字节数组后的数据。
  11. 关闭 bos 流。
  12. 通过 System.currentTimeMillis() 获取当前时间戳,作为结束时间 end2。
  13. 输出普通输出流和带缓存输出流的耗时差。
  14. 代码执行完毕。

测试结果

测试用例结果如下:

在这里插入图片描述

  测试结果显示,使用BufferedOutputStream后,IO操作的耗时大大减少,性能得到了很大程度的提升。

小结

  本文对Java中的IO操作进行了深入研究,重点关注了BufferedOutputStream的实现原理和使用方法。通过测试,我们也进一步验证了BufferedOutputStream在提高IO操作性能方面的作用。在实际开发中,我们应当更多地使用BufferedOutputStream来提高IO操作的效率,特别是对于大量的数据写入操作。

总结

  通过本文的介绍,我们了解到了BufferedOutputStream的概念、特点、使用方法和实现原理。同时,我们也了解到了如何正确使用BufferedOutputStream来提高IO操作的性能。在实际开发中,我们应当充分利用Java提供的缓存机制,来提高程序的性能。

☀️建议/推荐你


  无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学Java」,bug菌郑重承诺,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门Java编程,就像滚雪球一样,越滚越大,指数级提升。

  最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。

  同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。

📣关于我

  我是bug菌,CSDN | 掘金 | infoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2871528.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【系统架构师】-第4章-信息安全技术

1、基础知识 五要素&#xff1a; (1)机密性&#xff1a;确保信息不暴露给未授权的实体或进程。 (2)完整性&#xff1a;只有得到允许的人才能修改数据&#xff0c;并且能够判别出数据是否已被篡改。 (3)可用性&#xff1a;得到授权的实体在需要时可访问数据&#xff0c;即攻击…

力扣刷题Days20-151. 反转字符串中的单词(js)

目录 1,题目 2&#xff0c;代码 1&#xff0c;利用js函数 2&#xff0c;双指针 3&#xff0c;双指针加队列 3&#xff0c;学习与总结 1&#xff0c;正则表达式 / \s /&#xff1a; 2&#xff0c;结合使用 split 和正则表达式&#xff1a; 1,题目 给你一个字符串 s &am…

ChatGPT提示词方法的原理

关于提示词&#xff0c;我之前的一些文章可以参考&#xff1a; 【AIGC】AI作图最全提示词prompt集合&#xff08;收藏级&#xff09;https://giszz.blog.csdn.net/article/details/134815245?ydrefereraHR0cHM6Ly9tcC5jc2RuLm5ldC9tcF9ibG9nL21hbmFnZS9hcnRpY2xlP3NwbT0xMDExL…

RunnerGo测试平台的安装和使用

文章适用于想RunnerGo入门的同学&#xff0c;本人主要是后端&#xff0c;这里做一个入门的学习记录。想深入适用RunnerGo的同学可以参考官网文档&#xff1a; https://wiki.runnergo.cn/docs/ 这里我测试的代码是之前搭建的一个前后端分离小demo&#xff0c;代码地址是https:/…

Rocket MQ 从入门到实践

为什么要使用消息队列&#xff0c;解决什么问题&#xff1f;&#xff08;消峰、解藕、异步&#xff09; 消峰填谷 客户端》 网关 〉 消息队列》秒杀服务 异步解耦 消息队列中的重要概念理解。&#xff08;主题、消费组、队列&#xff0c;游标&#xff1f;&#xff09; 主题&…

Vulnhub - Toppo

希望和各位大佬一起学习&#xff0c;如果文章内容有错请多多指正&#xff0c;谢谢&#xff01; 个人博客链接&#xff1a;CH4SER的个人BLOG – Welcome To Ch4sers Blog Toppo 靶机下载地址&#xff1a;Toppo: 1 ~ VulnHub 搭建&#xff1a;创建任意虚拟机&#xff0c;然后…

【网络编程基础(一)】网络基础和SOCKET

这里写目录标题 1、网络三要素2、IPV4和IPV6区别3、网络交互3.1、交互模型图3.2、基础通信协议3.3、OSI参考模型与TCP/IP参考模型对应关系 4、SOCKET网络套接字4.1、SOCKET分类4.2、基于流式套接字的编程流程4.3、网络通信雏形4.4、socket函数4.4.1、socket函数示例 4.5、bind函…

idea 的基本配置

一、安装目录介绍 其中&#xff1a;bin 目录下&#xff1a; 二、配置信息目录结构 这是 IDEA 的各种配置的保存目录。这个设置目录有一个特性&#xff0c;就是你删除掉整个目录之后&#xff0c;重新启动 IntelliJ IDEA 会再自动帮你生成一个全新的默认配置&#xff0c;所以很多…

串的模式匹配(简单匹配、KMP以及手工算next/nextval)

简单模式匹配 思路&#xff1a;主串和字串进行匹配&#xff0c;设置i、j、k&#xff08;主串、子串和匹配起始下标&#xff09;主串和子串一开始都是从第一个位置&#xff08;k i&#xff09;&#xff0c;若当前主串和子串匹配成功那么i、j&#xff0c;若匹配不成功k、j 1&am…

24计算机考研调剂 | 宁波大学

北京信息科技大学接收调剂研究生 2024中国科学院宁波材料所与高校联合培养硕士研究生项目介绍 考研调剂招生信息 中国科学院宁波材料技术与工程研究所&#xff08;简称“宁波材料所”&#xff09;成立于2004年4月&#xff0c;是由中国科学院、浙江省人民政府、宁波市人民政府三…

算法第二十九天-森林中的兔子

森林中的兔子 题目要求 解题思路 重点&#xff1a;某个兔子回答x的时候&#xff0c;那么数组中最多循序x1个同花色的兔子同时回答x 我们可以通过举例子得出一下的规律&#xff1a; 我们统计数组中所有回答x的兔子的数量n&#xff1a; 若n%(x1)0&#xff0c;说明我们此时只需…

每日一题——LeetCode1694.重新格式化电话号码

方法一 模拟&#xff1a; 首先去除number里面的破折号和空格&#xff0c;取出纯数字组成的字符串str。 对于str每三个数分成一组&#xff0c;加一个破折号&#xff0c;当str的长度小于等于4时再分情况讨论&#xff0c;如果等于4就分为22形式&#xff0c;如果小于4&#xff0c…

哥斯拉流量webshell分析-->ASP/PHP

哥斯拉流量webshell分析 哥斯拉是继菜刀、蚁剑、冰蝎之后的又一个webshell利器&#xff0c;这里就不过多介绍了。 哥斯拉GitHub地址&#xff1a;https://github.com/BeichenDream/Godzilla 很多一线师傅不太了解其中的加解密手法&#xff0c;无法进行解密&#xff0c;这篇文章…

zabbix配置

1 下载zabbix 1 配置yum源 rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release- 5.0-1.el7.noarch.rpm yum clean all yum makecache fast 完成后会出现zabbix.repo文件 2安装zabbix服务 yum -y install zabbix-server-mysql zabbix-web-mysql z…

OpenHarmony—自适应布局

针对常见的开发场景&#xff0c;方舟开发框架提炼了七种自适应布局能力&#xff0c;这些布局可以独立使用&#xff0c;也可多种布局叠加使用。 下面我们依次介绍这几种自适应布局能力。 拉伸能力 拉伸能力是指容器组件尺寸发生变化时&#xff0c;增加或减小的空间全部分配给容…

继承 ResponseEntityExceptionHandler

目录 作用概述 示例-HttpRequestMethodNotSupportedException 示例-自定义异常处理 总示例 使用了ResponseEntityExceptionHandler后&#xff0c;为什么发生了异常后返回体为空 方法执行顺序 作用概述 这是一个方便的基类&#xff0c;用于希望通过 ExceptionHandler 方法…

【C语言_字符函数和字符串函数_复习篇】

目录 一、字符函数 1.1 字符分类函数 1.2 字符转换函数 二、字符串函数 2.1 strlen函数 2.1.1 strlen函数的使用 2.1.2 strlen函数的模拟实现 2.2 strcpy函数 2.2.1 strcpy函数的使用 2.2.2 strcpy函数的模拟实现 2.3 strcat函数 2.3.1 strcat函数的使用 2.3.2 strcat函数的…

基于深度学习LSTM+NLP情感分析电影数据爬虫可视化分析推荐系统(深度学习LSTM+机器学习双推荐算法+scrapy爬虫+NLP情感分析+数据分析可视化)

文章目录 基于深度学习LSTMNLP情感分析电影数据爬虫可视化分析推荐系统&#xff08;深度学习LSTM机器学习双推荐算法scrapy爬虫NLP情感分析数据分析可视化&#xff09;项目概述深度学习长短时记忆网络&#xff08;Long Short-Term Memory&#xff0c;LSTM&#xff09;机器学习协…

ISIS默认层级实验简述

ISIS被划分为三个层级&#xff1a;Level 1、Level 2和Level 1-2。 默认情况下&#xff0c;ISIS路由器属于level 1-2,是指同时支持Level 1和Level 2的路由器。路由器既可以在同一个自治系统内部进行路由选择&#xff0c;也可以将路由信息传递到其他自治系统。 实验拓扑图&#…

C# 打开文件对话框(OpenFileDialog)

OpenFileDialog&#xff1a;可以打开指定后缀名的文件&#xff0c;既能单个打开文件也能批量打开文件 /// <summary>/// 批量打开文档/// 引用&#xff1a;System.Window.Fomrs.OpenFileDialog/// </summary>public void OpenFile(){OpenFileDialog dialog new Op…