IO流实现

Rover20230226 / 2023-08-08 / 原文

目录

# IO体系
1. 字节流
	1). InputStream(输入流)
	2). OutputStream(输出流)
2. 字节缓冲流
    1). BufferedInputStream
    2). BufferedOutputStream
3. 字符流
	1). Reader
	2). Writer
# 补充
1. IO流
2. 字节流
	1). 读取中文出现乱码的原因
3. 字符流
	1). 编码表
	2). 编码和解码

IO体系

1. 字节流

1). InputStream(输入流)

这个抽象类是表示字节输入流的所有类的超类

实现

package com.itheima02.input;

import java.io.FileInputStream;
import java.io.IOException;

public class Demo {

    public static void main(String[] args) throws IOException {
        /*
            1. 创建输入流对象
                如果文件存在,那么就不会报错.
                如果文件不存在,那么就直接报错.
         */
        FileInputStream fis = new FileInputStream("day10/b.txt");

        //读数据
        int read = fis.read();
        System.out.println(read); // 97
        //强转成字符,底层会解码
        System.out.println((char)read); //a

        //释放资源
        fis.close();

    }
}

2). OutputStream(输出流)

这个抽象类是表示字节输出流的所有类的超类

实现

package com.itheima01.output;

import java.io.FileOutputStream;
import java.io.IOException;
/*
    TODO 写的原理
        1). 当前案例写出的97(10进制) 对应的二进制 0110 0001
        2). 写入文件的就是 0110 0001
        2). 当我们用文本编辑器, 打开文件的时候, 会进行解码 (ASCII码表)
                0110 0001 -> a
 */
public class Demo {

    public static void main(String[] args) throws IOException {

        //1. 创建流对象: 并指定文件位置
        FileOutputStream fos = new FileOutputStream("day10/a.txt");

        //2. 写
        fos.write(97);

        //3. 释放资源: IO流不关会一直在内存中,浪费资源
        fos.close();
    }
}

2. 字节缓冲流

1). BufferedInputStream

2). BufferedOutputStream

package com.itheima03.copy;

import java.io.*;

public class Demo02 {

    public static void main(String[] args) throws IOException {

        FileInputStream fis = new FileInputStream("C:/test2/a.mp4");
        FileOutputStream fos = new FileOutputStream("C:/test2/b.mp4");

        //字节缓冲流: 底层还是字节流 + 8K缓冲区
        BufferedInputStream bis = new BufferedInputStream(fis);
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        byte[] buffer = new byte[1024];
        int length;
        while((length = bis.read(buffer)) != -1){
            bos.write(buffer,0,length);
        }

        bos.close();
        bis.close();
    }
}

3. 字符流

1). Reader

package com.itheima04.character;

import java.io.FileReader;
import java.io.IOException;

public class Demo {

    public static void main(String[] args) throws IOException {
        //字节流: 一次读一个字节
//        FileInputStream fis = new FileInputStream("day10/a.txt");
        //字符流: 一次读一个字符
        FileReader fis = new FileReader("day10/a.txt");

        int content;
        while((content = fis.read()) != -1){
//            System.out.println(content);
            System.out.println((char)content);
        }

        fis.close();
    }
}

补充

1. IO流

# 集成电路
0. 电子元件构成的电路板: 只能存储0和1
1. cpu : 中央处理器(Central Processing Unit)
		1). 作用: 调度,计算
		2). 速度最快
2. 内存 : 临时性存储设备
		1). 作用: 缓存数据给cpu进行操作
		2). 特点: 通电工作,断电数据清空
		3). 速度次之
3. 硬盘 : 持久性存储设备
		1). 作用: 长久保存数据
		2). 速度最慢
# 读写
1. 读: 
		硬盘 -> 内存 -> cpu
2. 写:
		cpu -> 内存 -> 硬盘
# IO
0. 以内存为主语
1. input : 输入 (读)
	  	硬盘  -> 内存
2. output: 输出(写)
		内存 -> 硬盘

2. 字节流

1). 读取中文出现乱码的原因

在Idea中默认编码是UTF-8,中文用三个字节表示,而用字节流读出中文时,如果一次只读取一个字节就强转,就造成了乱码

1. 观察
    1). 一个英文字母1个字节
    2). 一个中文字符3个字节
2. 问题:
    1). 用字节流读中文会乱码
    2). 用字符流读中文不会乱码还很准确
3. 乱码
    1). 第一种: 不支持这个编码规则
    2). 第二种: 编码和解码使用的编码表不一致
4. 字符流
        字符流 = 字节流 + 编码表

2). 编码表

1. 编码表
    0). 作用: 将人类的字符和计算机01进行转换
    1). ASCII码 (美国)
         I. 占一个字节
         II. 128个字符
    2). ISO-8859-1码(欧洲: 拉丁码 latin)
        I. 占一个字节
        II. 256个字符
        兼容了ASCII码表
    3). GBK
        I. 占两个字节
        II. 65536个字符
          兼容了ASCII码表
    4). UTF-8
        I. 英文字母一个字节, 中文字符3个字节
        II. 开发中最常用编码
          windows中文版系统默认编码

3). 编码和解码

5. 编解码
    1). 编码(写)
            人看得懂 -> 计算机看得懂
             a -> 0110 0001
    2). 解码(读)
            计算机看得懂 -> 人看得懂
            0110 0001 -> a
    3). 编码和解码都会用到编码表
    4). 乱码
           I. 第一种: 不支持这个编码规则
           II. 第二种: 编码和解码使用的编码表不一致