呕心制作:IO流思想【授人以鱼不如授人以渔】

IO流详解

字节和字符的区别

字节

bit 【位】:计算机以0或者1来存储数据,1bit 代表一个0或者一个1
byte 【字节 | B】: 8个比特代表一个字节。 1 byte = 8 bit 或者 1 B = 8 bit

在这里插入图片描述

数据传输以 bit为单位
数据存储以 Byte 为单位

TIP:8bit = 1B 1024B = 1KB 1024KB = 1MB

字符

仓颉造字,字写的王八爪子画的还难看。所有给人看的符号统称为 字符

因为计算机最初是外国佬搞的,看的内容不复杂,只有大小写的英文字母和几个简单的符号
所以外国佬就搞了一个表来记录自己能看懂的的字符(英文字母) 也就是我们熟悉的ASCII码

在ASCII码中,一个字符仅占一个字节(Byte)

后来计算机全世界人都要用,总不能还只用个ASCII表吧。自己国家的数据不能保存,这怎么行。于是又是这个标准,又是那个标准。反正总有国家的字符没有录入进去。
直到好久之后,终于UTF-8问世了,几乎涵盖全世界全部字符。

在UTF-8中 一个字符有占一个字节的,2个、3个、4个的。
记忆点:UTF-8中,中文占三个字节
数字英文字母占一个字节。
很多国家字符只占两个字节。

总结

字节给计算机用的,字符是给人用的

什么是流

流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流。
通俗语:比如一部电影拷贝后的副本为什么能按照顺序播放,而不是一会播放这,一会播放那的呢。原因就是在流中拷贝是按照顺序拷贝的。【个人理解】
可以理解成是一个按照顺序拷贝的通道,类似与一个水管子一样

流的分类

按照流向分

​ 输入流 : 外部文件 ==> Java程序
​ 输出流 : Java程序 ==> 外部文件

按照传输数据单位分

​ 字节流 : 写成计算机能看懂的东西:全是0或1
​ 字符流:写成人能看懂的东西:符号

输入流输出流
字节InputStreamOutputStream
字符ReaderWriter

上述四种类均为抽象类不能进行实例化,其子类可以进行抽象化

按流的角色的不同分

​ 节点流 : 直接和数据源连接
​ 处理流/包装流 :连接节点流,对节点流包装,为程序提高更强大的读写功能

继承图

InputStream (字节输入流)

在这里插入图片描述

OutputStream (字节输出流)

在这里插入图片描述

Reader (字符输入流)

在这里插入图片描述

Writer (字符输出流)

在这里插入图片描述

总结:继承图很重要,你可以从其子类的构造方法中找到他的参数类型,如此,IO流的学习才会更加简单。

IO流的熟练使用

授人予鱼不如授人以渔
与其告诉你IO流中的每一个流如何使用,不如告诉你实质性的方法
一通百通

思想精华

节点流从硬盘读取,处理流来处理节点流处理的数据。

步骤

1、新建文件夹及其文件,文件中写入一首诗,命名诗经.txt
2、直接将文件的路径传入IO流实在太粗暴,我们引入FIle类来实现文件转换成Java对象
3、使用节点流直接接触数据源对象(刚刚的文件FIle对象)
4、使用处理流来处理节点流,实现程序的高读写性能
5、总结思想

程序实战

使用节点流接触数据源

package Test_project;

import org.junit.jupiter.api.Test;

import java.io.*;

public class test_ioStream {

    @Test
    public void io() throws IOException {
        //文件转成Java对象 (此时文件没有创建,借助File来创建)
        File filePath = new File("D:\\temp_file\\诗经.txt");


        //节点流  它是直接和数据源 (文件) 进行接触的
        FileOutputStream fileOutputStream = new FileOutputStream(filePath);
        String str = "床前明月光\n疑是地上霜\n举头望明月\n低头思故乡";
        //将数据写入  str.getBytes 是将数据转换成字节数组的形式传进去
        fileOutputStream.write(str.getBytes());
        fileOutputStream.close();

        //节点流 读取文件打印出来
        char[] buf =new char[6]; //一次读取六个字符
        int readLength = 0;     //接收读取字符的长度
        FileReader fileReader = new FileReader(filePath);
        while ((readLength = fileReader.read(buf)) != -1){
            System.out.println(new String(buf,0,readLength));
        }
        fileReader.close();
    }
}

//控制台

//床前明月光

//疑是地上霜

//举头望明月

//低头思故乡

在讲处理流之前先讲一个处理流的概念

BufferedInputStream

public class BufferedInputStream extends FilterInputStream {
    //....
    
    //第一个构造函数 一个参数类型,接收一个参数,参数类型为字节输入流
    public BufferedInputStream(InputStream in) {
        //....
    }
    //第二个构造函数 两个参数类型,一个参数类型为字节输入流 ,另外一个为int类型的size,表示的是缓冲的大小
    //第一个没有传size,默认大小是8192
    public BufferedInputStream(InputStream in, int size) {
        //...
    }
    //...
}
Q: 处理流为什么要去接收节点流?
A:因为速度更快啊

Q:为什么速度更快呢?
A: 节点流是从硬盘上直接读取数据的,而处理流是从让节点流从硬盘上读取自己缓冲区数据大小的数据(8192)存在内存上面。当缓冲区的数据用完后,再从硬盘里面拿到缓冲区大小的数据。

Q: 缓冲流一定比节点流更快吗?
A: 不一定。比如我们未给缓冲区设置大小,他的大小是8192。当我们调用read或Writer方法,会传入一次读取或写入的大小,当这个大小大于8192的时候,所谓的缓冲流速度大于节点流的速度的说法就不存在了。此时他两的速度一样。大多数情况下是没有这种场景的。

Q: 懂了,谢谢老师
A: 点赞,收藏,加关注
package Test_project;

import org.junit.jupiter.api.Test;

import java.io.*;

public class test_ioStream {

    @Test
    public void io() throws IOException {
        //文件转成Java对象 (此时文件没有创建,借助File来创建)
        File filePath = new File("D:\\temp_file\\诗经.txt");

        FileInputStream fileInputStream = new FileInputStream(filePath);
        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

        int readLen = 0;
        byte[] buf = new byte[1024]; //这里设置的太小,读取的数据乱码是因为字节和字符的转换关系。
        while (((readLen = bufferedInputStream.read(buf)) != -1)){
            System.out.println(new String(buf,0,readLen));
        }

        bufferedInputStream.close();

    }
}

//控制台
床前明月光
疑是地上霜
举头望明月
低头思故乡

对于IO的认识要站在流的角色的角度去写代码,如果仅仅停留在字符,字节,输入,输出的角度,学习将是十分缓慢的
至于更多的输入输出流,需要靠时间的积累,才能熟练掌握。
万变不离其宗,思想就是那么个思想。

Over

学习如逆水行舟,不进则退

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值