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

92-Java的缓冲流概述、体系、字节缓冲流使用

一、关于IO流我们还要学会什么?

1、缓冲流

  • 我们之前学习的流都是属于基础流,性能其实不是最好的,缓冲流读取数据的性能会更好!

2、转换流

  • 使用字符流读取中文不会乱码,原因是什么?
  • 那么如果读取的文件编码与代码编码不一致怎么办?

3、序列化

  • 如何把Java对象进行长久保存。

4、打印流

  • 开发中有一种使用极为方便,性能高效的写数据的流,使用的很多。

5、IO框架等

  • IO流原生的API使用起来其实挺麻烦的,有没有更好用的方式。



二、缓冲流

1、概述

  • 缓冲流也称为高效流、或者高级流。之前学习的字节流可以称为原始流。
  • 作用:缓冲流自带缓冲区,可以提高原始字节流、字符流读写数据的性能。

在这里插入图片描述



2、体系

在这里插入图片描述



小结

1、缓冲流的作用?

  • 缓冲流自带缓冲区,可以提高原始字节流、字符流读写数据的性能

2、缓冲流有几种?

  • 字节缓冲流
    • 字节缓冲输入流:BufferedInputStream
    • 字节缓冲输出流:BufferedOutputStream
  • 字符缓冲流
    • 字符缓冲输入流:BufferedReader
    • 字符缓冲输出流:BufferedWriter


3、字节缓冲流

  • 字节缓冲输入流:BufferedInputStream,提高了字节输入流读取数据的性能,读写功能上并无变化。
  • 字节缓冲输出流:BufferedOutputStream,提高了字节输出流读写数据的性能,读写功能上并无变化。

在这里插入图片描述


在这里插入图片描述

(1)字节缓冲流性能优化原理
  • 字节缓冲输入流自带了8KB缓冲池,以后我们直接从缓冲池读取数据,所以性能较好。
  • 字节缓冲输出流自带了8KB缓冲流,数据就直接写入到缓冲池中去,写数据性能极高了。


(2)字节缓冲流构造器
构造器说明
public BufferedInputStream(InputStream is)可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道,
从而提高字节输入流读取数据的性能
public BufferedOutputStream(OutputStream os)可以把低级的字节输出流包装成一个高级的缓冲字节输出流管道,
从而提高字节输出流读写数据的性能

package com.app.d1_byte_buffer;

import java.io.*;

/**
    目标:
        掌握如何将低级的字节输入、输出流包装成一个高级的缓冲字节输入、输出流管道,
        从而提高字节输入、输出流读取、读写数据的性能。
 */
public class ByteBufferDemo01 {
    public static void main(String[] args) {
        try (
            // 1、创建一个字节输入流管道与源文件路径接通
            InputStream is = new FileInputStream("E:\\JavaDevelop\\images\\3.jpg");
            // a.把原始的字节输入流包装成高级的缓冲字节输入流管道
            InputStream bis = new BufferedInputStream(is);

            // 2、创建一个字节输出流管道与目标文件路径接通
            OutputStream os = new FileOutputStream("E:\\JavaDevelop\\images\\4411.jpg");
            // b.把原始的字节输出流包装成高级的缓冲字节输出流管道
            OutputStream bos = new BufferedOutputStream(os);
        ) {
            // 3、拷贝源文件到目标文件路径下
            // 定义一个数组,用于每次读取1KB的字节数据
            byte[] buffer = new byte[1024];
            int len;    // 用于记录每次读取的字节数

            // 定义循环,不断读取源文件的字节数据,直到字节等于-1才结束
            while ( (len = bis.read(buffer)) != -1 ) {
                // 读取多少倒出多少
                bos.write(buffer, 0, len);
            }

            System.out.println("拷贝完成!");

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("拷贝失败!");
        }
    }
}
拷贝完成!

Process finished with exit code 0

在这里插入图片描述



小结

1、字节缓冲流为什么提高了操作数据的性能?

  • 字节缓冲流自带8KB缓冲区
  • 可以提高原始字节流、字符流读写数据的性能

2、字节缓冲流的功能如何调用?

在这里插入图片描述



4、字节缓冲流的性能分析

  • 我们已经说明了字节缓冲流的性能高效,但是没有直接感受到!!
  • 如何测试字节缓冲流的读写性能呢?


小范例:

分别使用不同的方式复制大视频观察性能情况!

需求

  • 分别使用低级字节流和高级字节缓冲流拷贝大视频,记录耗时。

分析

1、使用低级的字节流按照一个一个字节的形式拷贝文件。

2、使用低级的字节流按照一个一个字节数组的形式拷贝文件。

3、使用高级的字节缓冲流按照一个一个字节的形式复制文件。

4、使用高级的字节缓冲流按照一个一个字节数组的形式拷贝文件。

package com.app.d2_byte_buffer_time;

import java.io.*;

/**
    目标:通过使用不同方式的复制文件的形式观察基础字节流和高级字节缓冲流的性能区别
    需求:
        分别使用基础字节流和高级字节缓冲流拷贝文件,记录耗时。
 */
public class ByteBufferTimeDemo01 {
    // 定义两个变量,用于记录源文件路径和目标文件路径
    public static final String SRC_FILE = "E:/Python学习资源/Python视频类资料/Python入门视频/1-Python环境搭建/2-Python环境搭建.wmv";
    public static final String DEST_FILE = "E:/Python学习资源/Python视频类资料/Python入门视频/1-Python环境搭建/测试1/";

    public static void main(String[] args) {
        // copy1();    // 使用基础字节流按照一个一个字节的形式拷贝文件:速度非常慢,无法忍受!性能差!(淘汰!)
        copy2();    // 使用基础字节流按照一个一个字节数组的形式拷贝文件:速度比较慢,性能还行!(不推荐使用!)
        copy3();    // 使用字节缓冲流按照一个一个字节的形式拷贝文件:速度太慢,性能差!(不推荐使用!)
        copy4();    // 使用字节缓冲流按照一个一个字节数组的形式拷贝文件:速度飞快,性能ok!(推荐使用!!)
    }

    private static void copy4() {
        // 记录拷贝开始时间
        long startTime = System.currentTimeMillis();

        try (
                // 1、创建一个字节输入流管道与源文件接通
                InputStream is = new FileInputStream(SRC_FILE);
                // a.将基础字节输入流管道包装成字节缓冲输入流管道
                InputStream bis = new BufferedInputStream(is);

                // 2、创建一个字节输出流管道与目标文件接通
                OutputStream os = new FileOutputStream(DEST_FILE + "test04.wmv");
                // b.将基础字节输出流管道包装成字节缓冲输出流管道
                OutputStream bos = new BufferedOutputStream(os);
        ) {
            // 3、一个一个字节数组的形式拷贝文件
            byte[] buffer = new byte[1024]; // 每次读取1KB的字节数
            int len;    // 记录每次读取的字节数
            // 循环读取,读到-1结束循环
            while ( (len = bis.read(buffer)) != -1 ) {
                // 读多少取多少
                bos.write(buffer, 0, len);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        // 记录拷贝结束时间
        long endTime = System.currentTimeMillis();

        // 计算拷贝文件总耗时多少?
        System.out.println("使用字节缓冲流按照一个一个字节数组的形式拷贝文件总耗时:" + (endTime - startTime)/1000.0 + "秒");
    }



    private static void copy3() {
        // 记录拷贝开始时间
        long startTime = System.currentTimeMillis();

        try (
           // 1、创建一个字节输入流管道与源文件接通
           InputStream is = new FileInputStream(SRC_FILE);
           // a.将基础字节输入流管道包装成字节缓冲输入流管道
           InputStream bis = new BufferedInputStream(is);

           // 2、创建一个字节输出流管道与目标文件接通
           OutputStream os = new FileOutputStream(DEST_FILE + "test03.wmv");
           // b.将基础字节输出流管道包装成字节缓冲输出流管道
           OutputStream bos = new BufferedOutputStream(os);
        ) {
            // 3、一个一个字节的形式拷贝文件
            int len;    // 记录每次读取的字节数
            // 循环读取,读到-1结束循环
            while ( (len = bis.read()) != -1 ) {
                bos.write(len);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        // 记录拷贝结束时间
        long endTime = System.currentTimeMillis();

        // 计算拷贝文件总耗时多少?
        System.out.println("使用字节缓冲流按照一个一个字节的形式拷贝文件总耗时:" + (endTime - startTime)/1000.0 + "秒");
    }



    private static void copy2() {
        // 记录拷贝开始时间
        long startTime = System.currentTimeMillis();

        try (
            // 1、创建一个字节输入流管道与源文件接通
            InputStream is = new FileInputStream(SRC_FILE);
            // 2、创建一个字节输出流管道与源文件接通
            OutputStream os = new FileOutputStream(DEST_FILE + "test02.wmv");
        ) {
            // 3、一个一个字节数组的读取文件数据
            byte[] buffer = new byte[1024]; // 每次读取1KB的字节数
            int len;    // 用于记录每次读取的字节数
            // 循环读取,读到-1结束循环
            while ( (len = is.read(buffer)) != -1 ) {
                // 读多少取多少
                os.write(buffer, 0, len);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }

        // 记录拷贝结束时间
        long endTime = System.currentTimeMillis();

        // 计算拷贝文件总耗时多少?
        System.out.println("使用基础字节流按照一个一个字节数组的形式拷贝文件总耗时:" + (endTime - startTime)/1000.0 + "秒");
    }



    private static void copy1() {
        // 记录拷贝开始时间
        long startTime = System.currentTimeMillis();

        try (
            // 1、创建一个字节输入流管道与源文件接通
            InputStream is = new FileInputStream(SRC_FILE);
            // 2、创建一个字节输出流管道与目标文件接通
            OutputStream os = new FileOutputStream(DEST_FILE + "test01.wmv");
        ) {
            // 3、一个一个字节的读取文件数据
            int len;    // 记录每次读取的字节数
            // 循环读取,读到-1结束循环
            while ( (len = is.read()) != -1 ) {
                os.write(len);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }

        // 记录拷贝结束时间
        long endTime = System.currentTimeMillis();

        // 计算拷贝文件总耗时多少?
        System.out.println("使用基础字节流按照一个一个字节的形式拷贝文件总耗时:" + (endTime - startTime)/1000.0 + "秒");
    }
}
使用基础字节流按照一个一个字节数组的形式拷贝文件总耗时:2.032秒
使用字节缓冲流按照一个一个字节的形式拷贝文件总耗时:4.561秒
使用字节缓冲流按照一个一个字节数组的形式拷贝文件总耗时:1.033秒

Process finished with exit code 0



总结

1、推荐使用哪种方式提高字节流读写数据的性能?

  • 建议使用字节缓冲输入、输出流,结合字节数组的形式,目前来看是性能最优的组合



相关文章:

  • 检测网络框架越来越多
  • Gee引擎常用功能简介
  • 微信小程序 - - - - - 瀑布流效果实现
  • 前端面试问题(3)
  • 面试复习题二(综合类)
  • HCIA网络基础7-VRP和命令行基础
  • mybatis获取参数的两种方式: #{ } 和 ${ }
  • 为什么SDWAN成为了组网发展大趋势呢?
  • 谈谈什么是数据质量管理
  • 【Codecs系列】x265编码器(十一):快速运动估计搜索方法
  • 【Pandas 数据分析 2】数据结构
  • 家庭装修如何选择客厅灯具
  • k8s教程(09)-容器获取pod信息(Downward API)
  • C++【STL】【模板进阶】
  • fsh18罗德与施瓦茨FSH18手持式频谱分析仪18GHz
  • 【个人向】《HTTP图解》阅后小结
  • Android 架构优化~MVP 架构改造
  • CODING 缺陷管理功能正式开始公测
  • css系列之关于字体的事
  • Java 多线程编程之:notify 和 wait 用法
  • JavaScript HTML DOM
  • Javascript Math对象和Date对象常用方法详解
  • JavaScript函数式编程(一)
  • java正则表式的使用
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • Sass 快速入门教程
  • spring学习第二天
  • 不上全站https的网站你们就等着被恶心死吧
  • 动态魔术使用DBMS_SQL
  • 分类模型——Logistics Regression
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 力扣(LeetCode)21
  • 利用jquery编写加法运算验证码
  • 如何实现 font-size 的响应式
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 微信小程序开发问题汇总
  • 《码出高效》学习笔记与书中错误记录
  • ​ssh免密码登录设置及问题总结
  • (C++17) std算法之执行策略 execution
  • (待修改)PyG安装步骤
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (二)JAVA使用POI操作excel
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (七)c52学习之旅-中断
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (原創) 物件導向與老子思想 (OO)
  • (转)C#调用WebService 基础
  • (转)Mysql的优化设置
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET Core 将实体类转换为 SQL(ORM 映射)
  • .net反混淆脱壳工具de4dot的使用
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .NET牛人应该知道些什么(2):中级.NET开发人员