8.0、Java_IO流 - 如何利用缓冲区提高读写效率 ?

news2024/10/7 14:24:07

8.0、Java_IO流 - 如何利用缓冲区提高读写效率 ?

简单介绍:

        FileInputStream 通过字节的方式读取文件,适合读取所有类型的文件(图像、视频、文本文件等);Java 也提供了 FileReader 字符流 专门读取文本文件;

        FileOutputStream 通过字节的方式写数据到文件中,适合所有类型的文件;Java 也提供了 FileWriter 字符流 专门写入文本文件;

我们先用案列来了解一下,FileInputStream 和 FileOutputStream  ->

事先准备好一张图片 - 阿尼亚.jpg ->

案例 :创建 FileDemo2.java 文件,如下所示 ->

public class FlieDemo2 {
    public static void main(String[] args) throws FileNotFoundException {
        FileInputStream file = null;
        FileOutputStream file2 = null;
        try {
            //获取 D 盘下的 阿尼亚.jpg 文件
            file  = new FileInputStream("D:/阿尼亚.jpg");
            //获取 D 盘下的 pic.jpg 文件
            file2 = new FileOutputStream("D:/pic.jpg");
            int tmp = 0;
            while((tmp = file.read()) != -1) {
                //一个字节一个字节读取 阿尼亚.jpg 文件
                System.out.println(tmp);
                //将每一个读取出来的字节数据再写到pic.jpg 文件中去
                file2.write(tmp);
            }
        }catch(Exception e) {
            e.printStackTrace();
        //关闭流
        }finally {
            try {
                if(file != null) {
                    file.close();
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

执行main方法后输出结果如下所示 ->

 pic.jpg打开后如下所示 ->

说明我们成功将 阿尼亚.jpg 文件读取,且将读取出来的内容写入到了 pic.jpg 文件中;

数据缓冲区:

        看完这个案例之后明显的会感觉到有一个问题,那就是文件读写的效率太慢了,读一个写一个;
打个比方 ->
        我们在超市买了 100 斤大米,然后需要把这 100 斤大米扛回家,一次性肯定拿不动 100 斤,所以按照 案例 的方式就相当于我们一次拿一粒米回家,到家后每次从手中放下一粒米,再回到超市去继续拿......这样要拿放 N 次才能把这 100 斤拿完回家,显而易见效率低的不行......

我给大家提供两种解决方案,如下所示:

【解决方案 1】 
        我们可以做一个一次能装 20 斤大米的包,然后每次就能拿 20 斤大米,到家后每次从手中放下 20 斤大米,把包再拿回超市继续拿,拿五次就能完成;

注意 ->
        这里的包其实就相当于是创建了一个 数据缓冲区 [ 代码:byte[ ] buff = new byte(1024);缓冲区的大小必须为 2 的次幂 ] ;他能解决我们数据读写效率低下的问题;

用代码稍作解释 ->

FileInputStream fis = new FileInputStream("D:/rice.txt");

//创建缓冲区,大小为 1024 byte

byte[ ] buff = new byte[1024]; 

//一次拿一粒大米

fis.read();

//一次拿 20 斤大米

fis.read(buff);

FileOutputStream fos = new FileOutputStream("D:/home.txt");

//创建一个大小为 1024 的缓冲区,当然缓冲区只创建一次即可,可以复用

byte[ ] buff = new byte[1024];

//一次从手中放下一粒大米

fos.write();

//一次从从手中方法 20 斤大米

fos.write ( buff,起始位置,结束位置 ); 

解决方案 1 ,代码如下所示 ->

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileDemo3 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("D:/阿尼亚.jpg");
            fos = new FileOutputStream("D:/pic.jpg");
            byte[] buff = new byte[1024];
            int tmp = 0;
            //每次读取 1024 个字节的数据,将其放到缓冲区 buff 中
            while((tmp = fis.read(buff)) != -1) {
                //输出流,每次将数组 buff 中,从位置 0 开始一直到上面read()读取到的放在数组中的最后一个字节位置写,将其全部入文件 pic.jpg
                fos.write(buff,0,tmp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        //关闭流
        }finally {
            try {
                if(fos != null){
                    //关闭输出流
                    fos.close();
                }
                if(fis != null){
                    //关闭输出流
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

上述代码中:
        fos.write(buff,0,tmp);
用文件输出流对象调用 write(byte[ ],int,int);方法,[ 解释:每次将数组 buff 中,从位置 0 开始一直到上面 read( ) 读取到的放在数组中的最后一个字节位置写,将其全部入文件 pic.jpg ]

【解决方案 2】

         还是上面的案例,假设我们的力气超级大,一次性就能把 100 斤大米扛回去,此时我们就不是借助 20 斤的袋子了,而是创建一个能装 100 斤大米的袋子,把大米放进去,直接一次性扛回家就OK了;

        那么说白了方式二也是借助 缓冲区 来提高读写效率,只不过 缓冲区大小 不是自定义了,而是通过 " 文件输入流对象.available() " 方法去定义,该方法会返回当前输入流对象文件的大小预估值;

//创建文件输入流、文件输出流对象

FileInputStream fis = new FileInputStream("D:/阿尼亚.jpg");

FileOutputStream fos = new FileOutputStream(D:/pic.jpg);

//创建缓冲区 buff,缓冲区大小为 fis.available() ,该方法会预估 file.txt 文件大小

byte[ ] buff = new byte[ fis.available( ) ]; 

//读取文件内容,放到 buff 缓冲区中

fis.read( buff );

//将缓冲区 buff 中的数据写出到 pic.jpg 中

fos.write(buff);

        方案2 的代码与 方案1 代码基本相同,唯一不同之处 -> 就在于缓冲区的大小由 available() 方法来定义;所以这里就不做展示 方案2 代码了;

【 到这里要提醒一下大家 】

        在文件很大很大的情况,就不建议大家用 【解决方案 2】这种方式了,因为虽然省事一次性就搞定了,但是却十分的浪费内存空间资源;
        此时就应该使用 【解决方案 1】,虽然每次要搬多次,但不至于将内存空间资源都占了,最后可能导致程序崩溃;

        总结一句话就是:两种方案都是在用 空间 换取 效率;方案1 用较少的空间换取较低的效率,方案2  用较多的空间换取较高的效率;[ 当然,无论是 方案1 还是 方案2 都比不用缓冲区的效率要高得多得多 ];

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

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

相关文章

linux系统之lvm方式挂载磁盘

目录 一、简介二、创建LVM三、删除 一、简介 LVM:逻辑卷管理(Logical Volume Manager) 它是Linux环境下对磁盘分区进行管理的一种机制。LVM是建立在硬盘和分区之上的一个逻辑层,来提高磁盘分区管理的灵活性。它由ibm公司提出。目的:在原始设…

简单认识Nginx配置块location及rewrite

文章目录 一、location配置块1、分类2、location 常用的匹配规则3、location 优先级:4.location 匹配流程5、location实际使用规则1、直接匹配网站根目录首页2、处理静态文件请求3、通用规则 二、rewrite配置块1、简介2、rewrite跳转实现3、rewrite 执行顺序4.rewri…

数据结构——归并排序和计数排序的介绍

文章目录 归并排序归并排序的思想单趟排序的实现归并排序实现非递归版本的实现特性总结 计数排序计数排序的思想计数排序的实现特性总结 归并排序 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治(Divide and…

【Java】Map和Set

目录 一、搜索树 1、概念 2、操作-查找 3、操作-插入 4、操作-删除(难点) 6、性能分析 二、搜索 1、概念及场景 2、模型 三、Map 的使用 1、关于Map的说明 2、关于Map.Entry的说明,> 3、Map 的常用方法说明 4、TreeMap的使用案例 四、…

Django之ORM

一、Django模型层之ORM介绍 使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(增、删、改、查),而一旦谈到数据的管理操作,就需要用到数据库管理软件,例如mysql、oracle、Microsoft S…

护航行业安全!安全狗入选2023年度中国数字安全能力图谱(行业版)

近日,数世咨询正式发布了《2023年度中国数字安全能力图谱(行业版)》。 作为国内云原生安全领导厂商,安全狗也入选多个细项。 厦门服云信息科技有限公司(品牌名:安全狗)成立于2013年,…

8大service mesh框架大比拼,Istio不是唯一的选择!

文章目录 一、IsitoConsulLinkerdKumaOpen Service MeshMesheryTraefik MeshService Mesh Interface(SMI) 公众号: MCNU云原生,文章首发地,欢迎微信搜索关注,更多干货,第一时间掌握&#xff01…

Linux bluez蓝牙开发的准备工作

最近为了搞这个蓝牙的事情,忙碌了好几天,我就是想结合 bluez 的代码随便玩一下蓝牙设备,而且能够参考源码写点测试程序来操作这个蓝牙设备。这里只是说明 Linux 下的准备工作而非嵌入式的arm。 1,系统支持 我用的是真机安装的 D…

路由与交换技术(H3C)①——计算机网络基础

系列文章目录 ①——计算机网络基础 路由与交换技术(H3C)①——计算机网络概述 系列文章目录一 计算机网络概述1.1 计算机网络1.2 计算机网络的基本功能1.2.1 资源共享1.2.2 分布式处理与负载均衡1.2.3 综合信息服务 二 计算机网络的演进2.1 主机互联时…

Unity Editor扩展 实现一个Excel读表窗口

设计 Unity Editor窗口类 public class ExcelEditorWindow : EditorWindow {[MenuItem( "Frameworks/读表配置界面", false, 10 )]private static void Open(){Rect wr new Rect( 0, 0, 500, 500 );ExcelEditorWindow window ( ExcelEditorWindow ) EditorWindow.…

津津乐道设计模式 - 组合模式详解(以餐厅菜单系统举例让你快速掌握)

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~ 🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Mi…

基于Python所写的玛丽冒险设计

点击以下链接获取源码资源: https://download.csdn.net/download/qq_64505944/87953199 《玛丽冒险》程序使用说明 在PyCharm中运行《玛丽冒险》即可进入如图1所示的游戏主界面。 图1 游戏主界面 具体的操作步骤如下: (1)游戏…

数据库监控与调优【十四】—— COUNT语句优化

COUNT语句优化 有关COUNT的几个实验与结论 准备工作 create table user_test_count (id int primary key not null auto_increment,name varchar(45),age int,email varchar(60),birthday date ) engine innodb;insert into user_test_count (id, name, a…

算法设计与分析之回溯法

文章目录 1. 回溯法简介1.1 DFS的基本思想1.2 回溯法的基本思想1.3 回溯法和DFS的区别1.4 剪枝 2. 01背包问题:子集树2.1 问题介绍2.2 解决思路2.3 算法实现2.4 如何优化 3. 旅行商问题TSP:排序树3.1 问题介绍3.2 解决思路3.3 算法框架3.4 算法实现 4. 总…

项目一点点记录

kafka发布通知 kafka是消息队列,kafka采用发布订阅模式进行消息的生产与消费。在项目中,我们采用spring来整合kafka, 通过定义事件event来封装 点赞、关注、评论三类事件,event实体中有 事件主题topic,当前用户id&…

怎么给PDF添加图片水印?其实很简单,看这篇就会了!

许多人都意识到版权问题的重要性,尽管在日常生活中我们可能很少遇到,但在办公和学习中却经常涉及到此类问题。例如,我们辛辛苦苦制作的PDF文件,如何确保不被他人盗用呢?这就涉及到如何为PDF添加图片水印的问题,相当于…

无向图G的广度优先搜索和深度优先搜索以及完整程序

图的遍历算法有两种:广度优先搜索和深度优先搜索 一.广度优先搜索类似于层次遍历,需要借助辅助队列 空间复杂度为O(|V|);空间复杂度由辅助队列大小决定 时间复杂度为O(|V||E|) 为避免同一顶点被多次访问,设计visited[]来标记顶点 二.深度…

MyBatis 从初识到掌握

目录 今日良言:与其抱怨于黑暗,不如提灯向前行 一、初识MyBatis 1.MyBatis定义 2.为什么要学习MyBatis 3.MyBatis的创建 二、MyBatis的相关操作 1.增删改查操作 2.动态SQL使用 今日良言:与其抱怨于黑暗,不如提灯向前行 一…

UE4/5 通过Control rig的FullBody【蜘蛛模型,不用basic ik】

目录 根设置 FullBody IK 额外骨设置 ​编辑 晃动效果 根设置 第一步你需要准备一个蜘蛛模型,不论是官方示例或者是epic上购买的模型 然后我用的是epic上面购买的一个眼球蜘蛛: 第一步,我们从根创建一个空项【这个记得脱离父子级到root之…

SQLServer 2016 R2数据库新建、附加、分离、备份、还原、复制等基本操作

一、打开Microsoft SQL Server Management Studio 在桌面上找到图标,双击运行 打开Microsoft SQL Server Management Studio 17 输入服务器名称,选择SQL Server 身份验证,sa和sa密码,可以勾选记住密码,以便以后的登录…