BufferedOutputStream类讲解

2024-03-18 02:36

本文主要是介绍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电子书籍、简历模板等海量资料。


这篇关于BufferedOutputStream类讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/820932

相关文章

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

C++ vector的常见用法超详细讲解

《C++vector的常见用法超详细讲解》:本文主要介绍C++vector的常见用法,包括C++中vector容器的定义、初始化方法、访问元素、常用函数及其时间复杂度,通过代码介绍的非常详细,... 目录1、vector的定义2、vector常用初始化方法1、使编程用花括号直接赋值2、使用圆括号赋值3、ve

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

Python基础文件操作方法超详细讲解(详解版)

《Python基础文件操作方法超详细讲解(详解版)》文件就是操作系统为用户或应用程序提供的一个读写硬盘的虚拟单位,文件的核心操作就是读和写,:本文主要介绍Python基础文件操作方法超详细讲解的相... 目录一、文件操作1. 文件打开与关闭1.1 打开文件1.2 关闭文件2. 访问模式及说明二、文件读写1.

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

C++快速排序超详细讲解

《C++快速排序超详细讲解》快速排序是一种高效的排序算法,通过分治法将数组划分为两部分,递归排序,直到整个数组有序,通过代码解析和示例,详细解释了快速排序的工作原理和实现过程,需要的朋友可以参考下... 目录一、快速排序原理二、快速排序标准代码三、代码解析四、使用while循环的快速排序1.代码代码1.由快

Java集合中的List超详细讲解

《Java集合中的List超详细讲解》本文详细介绍了Java集合框架中的List接口,包括其在集合中的位置、继承体系、常用操作和代码示例,以及不同实现类(如ArrayList、LinkedList和V... 目录一,List的继承体系二,List的常用操作及代码示例1,创建List实例2,增加元素3,访问元

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

Python itertools中accumulate函数用法及使用运用详细讲解

《Pythonitertools中accumulate函数用法及使用运用详细讲解》:本文主要介绍Python的itertools库中的accumulate函数,该函数可以计算累积和或通过指定函数... 目录1.1前言:1.2定义:1.3衍生用法:1.3Leetcode的实际运用:总结 1.1前言:本文将详

Redis的Zset类型及相关命令详细讲解

《Redis的Zset类型及相关命令详细讲解》:本文主要介绍Redis的Zset类型及相关命令的相关资料,有序集合Zset是一种Redis数据结构,它类似于集合Set,但每个元素都有一个关联的分数... 目录Zset简介ZADDZCARDZCOUNTZRANGEZREVRANGEZRANGEBYSCOREZ