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

【进阶篇-Day13:JAVA中IO流之字节缓冲流的介绍】

目录

  • 1、IO流介绍
  • 2、IO流体系结构
    • 2.1 FileOutputStream 字节输出流
      • (1)字节输出流操作方法:
      • (2) 标准的关流代码:
    • 2.2 FileInputStream 字节输入流
      • (1)字节输入流操作方法:
    • 2.3 练习
  • 3、字节缓冲流
    • 3.1 字节缓冲流的使用:
    • 3.2 字节缓冲流的读写过程:
    • 3.3 案例:
      • 第一种:
      • 第二种:
      • 第三种:
      • 第四种:

1、IO流介绍

在这里插入图片描述

I就是input,即输入:从数据源读取数据。
O就是output,即输出:向数据目标写入数据。

2、IO流体系结构

在这里插入图片描述

2.1 FileOutputStream 字节输出流

(1)字节输出流操作方法:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

package com.itheima.stream.output;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class StreamOutputDemo1 {/*** 字节流写出数据:*     构造方法:*             1、public FileOutputStream(String name): 输出流关联文件,文件路径以字符串形式给出*             2、public FileOutputStream(File file): 输出流关联文件,文件路径以File形式给出**     成员方法:*             1、public void write(int i): 写出一个字节*             2、public void write(byte[] bys): 写出一个字节数组*     细节:*             输出流关联文件,文件如果不存在:会自动创建出来*                           如果文件存在:会清空现有的内容,然后再进行写入操作*                           如果就想要追加,那再FileOutputStream构造方法里的第二个参数传true即可*/public static void main(String[] args) throws IOException {//1、创建字节输出流对象,关联文件,第二个参数传true,表示文件内容追加写入,而非清空再写入FileOutputStream fos = new FileOutputStream("C:\\Users\\MSZ\\Desktop\\java_test\\dev\\A.txt", true);//2、写出数据fos.write(97);fos.write(98);fos.write(99);byte[] bytes = {97, 98, 99};//2.1 输出一个字节数组fos.write(bytes);//2.2 写出字节数组的一部分根据索引写入,如从1索引开始,到2索引结束fos.write(bytes, 1, 2);//2.3 如果要写出字符串,只需要调用字符串中的bytes方法即可,如下:fos.write("我想要变富裕".getBytes());//3、流对象使用完毕后需关闭fos.close();}
}

(2) 标准的关流代码:

上述代码中,我们将字节输出流的异常抛到上层调用方法里了,但一般我们需要使用try-catch来处理,下面来介绍:

在这里插入图片描述

package com.itheima.stream.output;
import java.io.FileOutputStream;
import java.io.IOException;public class StreamOutputDemo2 {/*** IO流的异常处理方式:jdk7版本之前*/public static void main(String[] args) {FileOutputStream fos = null;try {fos = new FileOutputStream("D:\\A.txt");fos.write("xxx".getBytes());System.out.println(10/0);//在关闭流之前如果有其他异常,那当前的try-catch就捕获不到了,因此关闭流放在finally里}catch (IOException e){e.printStackTrace();}finally {if (fos != null){try {fos.close();} catch (IOException e) {e.printStackTrace();}}}}
}

上面是jdk7之前的写法,写法很繁琐,所以后续的jdk7、jdk8使用了新的写法,如下:

在这里插入图片描述
在这里插入图片描述

package com.itheima.stream.output;
import java.io.FileOutputStream;
import java.io.IOException;public class StreamOutputDemo3 {/*** IO流的异常处理方式:jdk7版本之后*/public static void main(String[] args) {    //只需要将需要关闭文件流的代码放入try的括号中即可,在运行过程中会自动调用close方法try (FileOutputStream fos = new FileOutputStream("D:\\A.txt")) {fos.write("xxx".getBytes());}catch (IOException e){throw new RuntimeException("我报错了。。。");}}
}

在这里插入图片描述

2.2 FileInputStream 字节输入流

(1)字节输入流操作方法:

在这里插入图片描述
在这里插入图片描述

package com.itheima.stream.input;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;public class StreamInputDemo1 {/*** 字节流读取数据*     1、public int read():读取单个字节*         - 如果的读取完了,那么就会返回 -1**     2、public int read(byte[] bys):读取一个字节数组*         - 将读取到的字节,存入数组容器,返回读取到的有效字节个数*/public static void main(String[] args) {try (FileInputStream fis = new FileInputStream("C:\\Users\\MSZ\\Desktop\\java_test\\dev\\A.txt")) {//try()会自动调用fis.close()方法,切记切记//1、fis.read()方法每次读取一个字节,如果的读取完了,那么就会返回-1,因此我们可以使用-1来判断是不是读取完了int i;while ((i = fis.read()) != -1){System.out.println(i);}//2、fis.read(byte[] bys)方法将读取到的字节,存入数组容器,返回读取到的有效字节个数//2.1 准备一个数组,用于装字节byte[] bys = new byte[2];//2.2 读取数据,并返回有效字节数int len = fis.read(bys);System.out.println(Arrays.toString(bys));} catch (IOException e) {throw new RuntimeException(e);}}
}

如果定义的数组长单不够,继续读取的话,会出现如下效果:

在这里插入图片描述

可发现,最后两次有残留数据,如倒数第二行[101,100]中的100,倒数第一行的[101,100]。如何解决这个问题呢?
答:将读取出来的数据转换为字符串,使用下面的方法做转换:

在这里插入图片描述
因此,改造上述代码如下:

package com.itheima.stream.input;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;public class StreamInputDemo1 {/*** 字节流读取数据*     1、public int read():读取单个字节*         - 如果的读取完了,那么就会返回 -1**     2、public int read(byte[] bys):读取一个字节数组*         - 将读取到的字节,存入数组容器,返回读取到的有效字节个数*/public static void main(String[] args) {try (FileInputStream fis = new FileInputStream("C:\\Users\\MSZ\\Desktop\\java_test\\dev\\A.txt")) {//try()会自动调用fis.close()方法,切记切记//1、fis.read()方法每次读取一个字节,如果的读取完了,那么就会返回-1,因此我们可以使用-1来判断是不是读取完了
//            int i;
//            while ((i = fis.read()) != -1){
//                System.out.println(i);
//            }//2、fis.read(byte[] bys)方法将读取到的字节,存入数组容器,返回读取到的有效字节个数//2.1 准备一个数组,用于装字节byte[] bys = new byte[2];//2.2 循环读取数据,并转换成字符串int len;while ((len = fis.read(bys)) != -1){System.out.print(new String(bys, 0, len));//每次将有效长度的数组转换为字符串}} catch (IOException e) {throw new RuntimeException(e);}}
}

在这里插入图片描述

2.3 练习

在这里插入图片描述

package com.itheima.stream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class FileStreamTest1 {public static void main(String[] args) {try(FileInputStream fis = new FileInputStream("D:\\嘿嘿.png");FileOutputStream fos = new FileOutputStream("E:\\嘿嘿.png")){//会自动调用close方法的//1、读入字节流int len;//每次读取的长度byte[] bys = new byte[1024];//每次读取的字节放在此数组while ((len = fis.read(bys)) != -1){//2、将每次读取的,写入字节流fos.write(bys, 0, len);}}catch (IOException e){throw new RuntimeException("读取或输出字节流报错" + e.getMessage());}}
}

3、字节缓冲流

上面我们为了提高读取效率,定义了一个数组,其实java中已经帮我们实现了这个功能,这就是字节缓冲流存在的意义,下面看怎么用的。

3.1 字节缓冲流的使用:

在这里插入图片描述

package com.itheima.stream;
import java.io.*;public class BufferedStreamDemo1 {/*** 字节缓冲流在源代码中内置了字节数组,可以提高读写效率* 字节缓冲输入流: public BufferedInputStream(InputStream in)* 字节缓冲输出流: public BufferedOutputStream(OutputStream out)*/public static void main(String[] args) throws IOException {mothed1();//抛出异常写法mothed2();//捕获异常写法}/*** 将异常传给调用他的地方*/private static void mothed1() throws IOException {//1、创建字节缓冲区输入流BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\嘿嘿.png"));//2、创建字节缓冲区输出流BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\嘿嘿.png"));//3、读取并写入int len;while ((len = bis.read()) != -1) {bos.write(len);//写入到bos指定的地方}//4、关闭流,注意:只需要关闭缓冲输入输出流即可bis.close();bos.close();}/*** try-catch捕获异常*/private static void mothed2() {//关闭流操作,自动在try()里已经实现了try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\嘿嘿.png"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\嘿嘿.png"))) {int len;while ((len = bis.read()) != -1){bos.write(len);//写入到bos指定的地方}} catch (IOException e) {throw new RuntimeException("报错了" + e.getMessage());}}
}

3.2 字节缓冲流的读写过程:

在这里插入图片描述

3.3 案例:

在这里插入图片描述

package com.itheima.stream;
import java.io.*;
public class BufferedStreamDemo {/*** 四种拷贝方法:*     1、普通流单个字节拷贝*     2、普通流 + 自定义数组拷贝*     3、缓冲流单个字节拷贝*     4、缓冲流 + 自定义数组拷贝*/public static void main(String[] args) throws IOException {long start = System.currentTimeMillis();
//        method1(); //24386000
//        method2(); //4208
//        method3(); //24386method4(); //3293long end = System.currentTimeMillis();System.out.println(end - start);}/*** 1、普通流单个字节拷贝*/public static void method1() throws IOException {//1、创建字节输入流FileInputStream fis = new FileInputStream("D:\\英雄联盟.mp4");//2、创建字节输出流FileOutputStream fos = new FileOutputStream("E:\\英雄联盟.mp4");//3、读取:每次读一个并写入一个int len;while ((len = fis.read()) != -1){fos.write(len);}//4、关闭流fis.close();fos.close();}/*** 2、普通流 + 自定义数组拷贝*/public static void method2() throws IOException {//1、创建字节输入流FileInputStream fis = new FileInputStream("D:\\英雄联盟.mp4");//2、创建字节输出流FileOutputStream fos = new FileOutputStream("E:\\英雄联盟.mp4");//3、读取:每次读一个数组的内容,并写入一个数组的内容byte[] bys = new byte[4096];int len;while ((len = fis.read(bys)) != -1){fos.write(bys, 0, len);}//4、关闭流fis.close();fos.close();}/*** 3、缓冲流单个字节拷贝*/public static void method3() throws IOException {//1、创建缓冲字节输入流BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\英雄联盟.mp4"));//2、创建缓冲字节输出流BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\英雄联盟.mp4"));//3、读取:int len;while ((len = bis.read()) != -1){bos.write(len);}//4、关闭流bis.close();bos.close();}/*** 4、缓冲流 + 自定义数组拷贝*/public static void method4() throws IOException {//1、创建缓冲字节输入流BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\英雄联盟.mp4"));//2、创建缓冲字节输出流BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\英雄联盟.mp4"));//3、读取:每次读一个数组的内容到缓冲内存中,并写入一个数组的内容到硬盘byte[] bys = new byte[4096];int len;while ((len = bis.read(bys)) != -1){bos.write(bys, 0, len);}//4、关闭流bis.close();bos.close();}
}

第一种:

在这里插入图片描述

第二种:

在这里插入图片描述

第三种:

在这里插入图片描述
上述解释:

先从硬盘先直接读取了8192个字节,放入缓冲输入流的数组内存中,然后再一个一个地取出放入缓冲输出流的数组内存中,最后一次性写出8192个字节到硬盘。那这样为啥比一个一个的快呢?
答:因为一个一个的取是在内存中完成的,因此比方法一要快的多。

第四种:

在这里插入图片描述

那这四种方法在实际使用时怎么选择呢?
答:一般选择二或者四,因为这两种效率差不多,并且二代码更简洁,所以更推荐二。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Redis缓存穿透、击穿和雪崩的理解和解决思路
  • 如何有效管理众多账号密码:选择适合你的密码管理工具
  • kafka架构+原理+源码
  • PHP $_POST 变量
  • 全链路追踪 性能监控,GO 应用可观测全面升级
  • Python数值计算(9)
  • 大数据-54 Kafka 安装配置 环境变量配置 启动服务 Ubuntu配置 ZooKeeper
  • 【iOS】—— iOS持久化
  • 【Git】.gitignore全局配置与忽略匹配规则详解
  • 快速识别音频文件转成文字
  • 实战:安装ElasticSearch 和常用操作命令
  • C#中的异步编程:Task、Await 和 Async
  • Settings搜索系统SettingsIntelligence
  • 数说故事 | 大数据洞察宠物消费市场数据
  • java-静态工具类获取YAML配置文件中的值
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • co模块的前端实现
  • gf框架之分页模块(五) - 自定义分页
  • Git学习与使用心得(1)—— 初始化
  • JavaScript设计模式之工厂模式
  • JS字符串转数字方法总结
  • Lucene解析 - 基本概念
  • PaddlePaddle-GitHub的正确打开姿势
  • Python实现BT种子转化为磁力链接【实战】
  • Vue全家桶实现一个Web App
  • yii2中session跨域名的问题
  • 阿里云购买磁盘后挂载
  • 将 Measurements 和 Units 应用到物理学
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 聚类分析——Kmeans
  • 前端自动化解决方案
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 山寨一个 Promise
  • 什么软件可以剪辑音乐?
  • 算法-图和图算法
  • 正则表达式
  • mysql面试题分组并合并列
  • # Redis 入门到精通(七)-- redis 删除策略
  • #include<初见C语言之指针(5)>
  • (02)vite环境变量配置
  • (1) caustics\
  • (5)STL算法之复制
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (9)STL算法之逆转旋转
  • (LLM) 很笨
  • (MATLAB)第五章-矩阵运算
  • (第三期)书生大模型实战营——InternVL(冷笑话大师)部署微调实践
  • (附源码)springboot教学评价 毕业设计 641310
  • (七)c52学习之旅-中断
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (四)进入MySQL 【事务】
  • (一)u-boot-nand.bin的下载
  • (转载)OpenStack Hacker养成指南