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

news2024/11/28 12:50:37

目录

  • 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(); //24386
        method4(); //3293
        long 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个字节到硬盘。那这样为啥比一个一个的快呢?
答:因为一个一个的取是在内存中完成的,因此比方法一要快的多。

第四种:

在这里插入图片描述

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

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

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

相关文章

Glove-词向量

文章目录 共现矩阵共线概率共线概率比词向量训练总结词向量存在的问题 上一篇文章词的向量化介绍了词的向量化,词向量的训练方式可以基于语言模型、基于窗口的CBOW和SKipGram的这几种方法。今天介绍的Glove也是一种训练词向量的一种方法,他是基于共现概率…

【每日一题】【回溯+二进制优化】[USACO1.5] 八皇后 Checker Challenge C\C++\Java\Python3

P1219 [USACO1.5] 八皇后 Checker Challenge [USACO1.5] 八皇后 Checker Challenge 题目描述 一个如下的 6 6 6 \times 6 66 的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的…

Python设置Excel单元格中的部分文本颜色

文章目录 一、概述二、效果三、示例 一、概述 openpyxl (目前)不支持设置单元格内部分字体颜色 xlsxwriter 支持设置单元格内部分字体颜色(创建新的Excel) 二、效果 三、示例 """ Python设置Excel单元格中的部分…

昇思 25 天学习打卡营第 24 天 | MindSpore Pix2Pix 实现图像转换

1. 背景: 使用 MindSpore 学习神经网络,打卡第 24 天;主要内容也依据 mindspore 的学习记录。 2. PixPix 介绍: MindSpore 的 Pix2Pix 图像转换 介绍 Pix2Pix是基于条件生成对抗网络(cGAN, Condition Generative Ad…

Oracle如何跨越incarnation进行数据恢复

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等) 公众号:老苏畅谈运维 欢迎关注本人公众号,更多精彩与您分享…

Skywalking 入门与实战

一 什么是 Skywalking? Skywalking 时一个开源的分布式追踪系统,用于检测、诊断和优化分布式系统的功能。它可以帮助开发者和运维人员深入了解分布式系统中各个组件之间的调用关系、性能瓶颈以及异常情况,从而提供系统级的性能优化和故障排查。 1.1 为…

笑谈“八股文”,人生不成文

一、“八股文”在实际工作中是助力、阻力还是空谈? 作为现在各类大中小企业面试程序员时的必问内容,“八股文”似乎是很重要的存在。但“八股文”是否能在实际工作中发挥它“敲门砖”应有的作用呢?有IT人士不禁发出疑问:程序员面试…

AcWing3302. 表达式求值

代码解释 while(j<str.size()&&isdigit(str[j])){xx*10str[j]-0;}把字符串中里面连续的数字转化为int类型变量&#xff0c;比如输入996/3328,正常的挨个字符扫描只能扫到’9’,‘9’,‘6’,但是按照上面代码的算法是重新开了一个循环&#xff0c;直接把’9’,‘9’,…

【网络请求调试神器,curl -vvv 返回都有什么】

curl -vvv 是一个用于在命令行中执行 HTTP 请求的命令&#xff0c;其中 -vvv 是一个选项&#xff0c;用于启用详细的调试输出。 vvv: 这是一个选项&#xff0c;表示启用详细的调试输出。每个 v 增加调试信息的详细程度&#xff0c;vvv 是最高级别的详细输出。 详细输出包括&a…

【shell脚本快速一键部署项目】

目录 一、环境拓扑图二、主机环境描述三、注意四、需求描述五、shell代码的编写六、总结 一、环境拓扑图 二、主机环境描述 主机名主机地址需要提供的服务content.exam.com172.25.250.101提供基于 httpd/nginx 的 YUM仓库服务ntp.exam.com172.25.250.102提供基于Chronyd 的 NT…

GPU池化:点燃Jupyter Notebook中的AI算力之火

数据科学的火花在Jupyter Notebook中点燃&#xff0c;而GPU的加入&#xff0c;让这火焰更加炽热&#xff01;随着人工智能领域的飞速发展&#xff0c;利用GPU加速已成为数据科学和机器学习领域的新常态。 今天&#xff0c;我们要探索的&#xff0c;是Jupyter Notebook与GPU池化…

PHP学习:PHP基础

以.php作为后缀结尾的文件&#xff0c;由服务器解析和运行的语言。 一、语法 PHP 脚本可以放在文档中的任何位置。 PHP 脚本以 <?php 开始&#xff0c;以 ?> 结束。 <!DOCTYPE html> <html> <body><h1>My first PHP page</h1><?php …

spaCy语言模型下载

spaCy 是一个基于 Python 编写的开源自然语言处理&#xff08;NLP&#xff09;库&#xff0c;它提供了一系列的工具和功能&#xff0c;用于文本预处理、文本解析、命名实体识别、词性标注、句法分析和文本分类等任务。 spaCy支持多种语言模型对文本进行处理&#xff0c;包括中文…

自己在Vmware中搭建mqtt服务器

前言 在学习某个HMI的使用的时候&#xff0c;这个HMI带有MQTT功能&#xff0c;就想着自己是不是能够搭建一个自己的MQTT的服务器呢&#xff1f; 一、mqtt 自己搭建之一&#xff1a;Mosquitto 自己搭建MQTT服务器需要安装和运行MQTT服务软件&#xff0c;比如常用的是Mosquitto…

Tkinter简介与实战(1)

Tkinter简介与实战---实现一个计算器 Tkinter简介安装环境和安装命令WindowsmacOSLinux 注意事项使用正确的包管理器&#xff1a;检查安装完整性&#xff1a;更新 Python&#xff1a;使用虚拟环境&#xff1a; 一个实战例子-----计算器1.创建窗口&#xff1a;2.创建 GUI 组件&a…

学习大数据DAY27 Linux最终阶段测试

满分&#xff1a;100 得分&#xff1a;72 目录 一选择题&#xff08;每题 3 分&#xff0c;共计 30 分&#xff09; 二、编程题&#xff08;共 70…

ANSYS仿真DDR4的眼图

1 眼图的基本知识 对于数字信号&#xff0c;高低电平转换可以组合在多个序列中。以3位为例&#xff0c;总共有000-111和8种组合。在时域中&#xff0c;根据某个参考点对足够多的序列进行对齐&#xff0c;然后将波形叠加形成眼图&#xff0c;如下图所示。 图&#xff1a;眼图中…

JavaScript object find 示例

https://andi.cn/page/621631.html

从信息论的角度看微博推荐算法

引言 在数字时代&#xff0c;推荐系统已成为社交媒体和其他在线服务平台的核心组成部分。它们通过分析用户行为和偏好&#xff0c;为用户提供个性化的内容&#xff0c;从而提高用户满意度和平台的参与度。推荐系统不仅能够增强用户体验&#xff0c;还能显著提升广告投放的效率…

angular入门基础教程(一)环境配置与新建项目

ng已经更新到v18了&#xff0c;我对他的印象还停留在v1,v2的版本&#xff0c;最近研究了下&#xff0c;与react和vue是越来越像了&#xff0c;所以准备正式上手了。 新官网地址:https://angular.cn/ 准备条件 nodejs > 18.0vscodeng版本18.x(最新的版本) {"name&qu…