探究BufferedOutputStream的奥秘

news2024/11/14 15:09:38

在这里插入图片描述
  咦咦咦,各位小可爱,我是你们的好伙伴——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://www.coloradmin.cn/o/1535271.html

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

相关文章

[音视频学习笔记]六、自制音视频播放器Part1 -新版本ffmpeg,Qt +VS2022,都什么年代了还在写传统播放器?

前言 参考了雷神的自制播放器项目&#xff0c;100行代码实现最简单的基于FFMPEGSDL的视频播放器&#xff08;SDL1.x&#xff09; 不过老版本的代码参考意义不大了&#xff0c;我现在准备使用Qt VS2022 FFmpeg59重写这部分代码&#xff0c;具体的代码仓库如下&#xff1a; …

本地化语音识别、视频翻译和配音工具:赋能音频和视频内容处理

随着人工智能技术的飞速发展&#xff0c;语音识别、视频翻译和配音等任务已经变得更加容易和高效。然而&#xff0c;许多现有的工具和服务仍然依赖于互联网连接&#xff0c;这可能会导致延迟、隐私问题和成本问题。为了克服这些限制&#xff0c;我们介绍了一种本地化、离线运行…

RCE漏洞

RCE漏洞概述 远程命令执行/代码注入漏洞&#xff0c;英文全称为Reote Code/CommandExecute&#xff0c;简称RCE漏洞。PHPJava等Web开发语言包含命令执行和代码执行函数,攻击者可以直接向后台服务器远程执行操作系统命今或者运行注入代码&#xff0c;进而获取系统信息、控制后台…

社交媒体的未来:探讨Facebook的发展趋势

引言 在数字化时代&#xff0c;社交媒体已经成为人们日常生活中不可或缺的一部分。作为全球最大的社交媒体平台之一&#xff0c;Facebook一直在不断地追求创新&#xff0c;以满足用户日益增长的需求和适应科技发展的变革。本文将探讨Facebook在未来发展中可能面临的挑战和应对…

10W字解析 SpringBoot技术内幕文档,实战+原理齐飞,spring事务实现原理面试

第3章&#xff0c;Spring Boot构造流程源码分析&#xff0c;Spring Boot的启动非常简单&#xff0c;只需执行一个简单的main方法即可&#xff0c;但在整个main方法中&#xff0c;Spring Boot都做了些什么呢&#xff1f;本章会为大家详细讲解Spring Boot启动过程中所涉及的源代码…

Linux下Docker部署中间件(Mysql、Redis、Nginx等)

我的自备文件 文件传输 内网下直接上传很慢 使用scp命令将另一台服务器上的文件传输过来&#xff1b;在已有文件的服务器往没有文件的服务器传输 scp -r 传输的文件夹/文件 root要传输的地址:放置的地址 scp -r tools root172.xx.x.xxx:/data/ 安装二进制文件、脚本及各中间件…

《深入解析 C#》—— C# 3 部分

文章目录 第三章 C#3&#xff1a;LINQ及相关特性3.1 自动实现属性&#xff08;*&#xff09;3.2 隐式类型 var&#xff08;*&#xff09;3.3 对象和集合初始化3.3.1 对象初始化器3.3.2 集合初始化器 3.4 匿名类型3.4.1 基本语法和行为3.4.2 编译器生成类型3.4.3 匿名类型的局限…

Hive和Hadoop版本对应关系

通过 Downloads (apache.org) 即可查看

MySQL的基本操作

目录 引言 一、SQL语句简介 &#xff08;一&#xff09;SQL通用语法 &#xff08;二&#xff09;SQL分类 &#xff08;三&#xff09;数据类型 1.数值类型 2.字符串类型 3.日期/时间类型 4.修饰符 二、登录mysql服务 三、SQL语句操作 &#xff08;一&#xff09;DD…

vue3 + ts +element-plus + vue-router + scss + axios搭建项目

本地环境&#xff1a; node版本&#xff1a;20.10.0 目录 一、搭建环境 二、创建项目 三、修改页面 四、封装路由vue-router 五、element-plus 六、安装scss 七、封装axios 一、搭建环境 1、安装vue脚手架 npm i -g vue/cli 2、查看脚手架版本 vue -V3、切换路径到需…

Studio One 6 Mac中文版破解版下载(附Mac版注册机)

Studio One 6 Mac版是一款强大的音乐创作与制作软件&#xff0c;其可通过更简单的方式来录制音频及进行MIDI制作&#xff0c;并提供丰富的专业功能。它具备音乐创作、录音混缩、MIDI编辑、音频处理、Loops拼接、视频配乐和母带与专辑制作等功能。软件提供了强大的音频性能&…

在iOS中安装

返回&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;使用CUDA 为Tegra构建OpenCV-CSDN博客 下一篇&#xff1a; 警告&#xff01; 本教程可以包含过时的信息。 所需软件包 CMake 2.8.8 或更高版本Xcode 4.2 或更高版本 从 G…

笔试总结01

1、spring原理 1、spring原理 spring的最大作用ioc/di,将类与类的依赖关系写在配置文件中&#xff0c;程序在运行时根据配置文件动态加载依赖的类&#xff0c;降低的类与类之间的藕合度。它的原理是在applicationContext.xml加入bean标记,在bean标记中通过class属性说明具体类…

旅游小程序的市场与发展趋势

随着科技的发展&#xff0c;移动互联网已经成为我们生活中不可或缺的一部分。在这个时代&#xff0c;小程序已经成为了一种新的趋势&#xff0c;尤其是在旅游行业。那么&#xff0c;旅游小程序有哪些市场&#xff0c;发展趋势又怎么样呢&#xff1f; 一、旅游小程序的市场 1. 用…

AI原生安全 亚信安全首个“人工智能安全实用手册”开放阅览

不断涌现的AI技术新应用和大模型技术革新&#xff0c;让我们感叹从没有像今天这样&#xff0c;离人工智能的未来如此之近。 追逐AI原生&#xff1f;企业组织基于并利用大模型技术探索和开发AI应用的无限可能&#xff0c;迎接生产与业务模式的全面的革新。 我们更应关心AI安全原…

Linux的基本使用

1.Linux的背景 1.1什么Linux Linux是⼀个操作系统.和Windows是"并列"的关系. 1.2Linux系统的优势 1. 开源(意味着免费,便宜) 2. 稳定(Linux可以运⾏很多年,都不会发⽣重⼤问题) 3. 安全(Linux只有管理员或者特定⽤⼾才能访问Linux内核) 4. ⾃由(不会被强加商业产品和…

JVM内存划分

一、运行时数据区域 堆、方法区&#xff08;元空间&#xff09;、虚拟机栈、本地方法栈、程序计数器。 Heap(堆)&#xff1a; 对象的实例以及数组的内存都是要在堆上进行分配的&#xff0c;堆是线程共享的一块区域&#xff0c;用来存放对象实例&#xff0c;也是垃圾回收&…

用大语言模型控制交通信号灯,有效缓解拥堵!

城市交通拥堵是一个全球性的问题&#xff0c;在众多缓解交通拥堵的策略中&#xff0c;提高路口交通信号控制的效率至关重要。传统的基于规则的交通信号控制&#xff08;TSC&#xff09;方法&#xff0c;由于其静态的、基于规则的算法&#xff0c;无法完全适应城市交通不断变化的…

RK3568笔记二十:PP-YOLOE部署测试

若该文为原创文章&#xff0c;转载请注明原文出处。 注&#xff1a;转换测试使用的是Autodl服务器&#xff0c;CUDA11.1版本&#xff0c;py3.8。 一、PP-YOLOE环境安装 创建环境 # 使用 conda 创建一个名为 PaddleYOLO 的环境&#xff0c;并指定 python 版本conda create -n…

[flask]flask的路由

路由的基本定义 路由就是一种映射关系。是绑定应用程序&#xff08;视图&#xff09;和url地址的一种一对一的映射关系&#xff01;在开发过程中&#xff0c;编写项目时所使用的路由往往是指代了框架/项目中用于完成路由功能的类&#xff0c;这个类一般就是路由类&#xff0c;…