Java IO流 02 字节流和字符流

2.1 IO 分类


在这里插入图片描述
根据 数据的 流向 我们 分为:输入流输出流

  • 输入流:把数据 从 其他设备上 读取到 内存中的 流。
  • 输出流:把数据 从 内存中 写出 到 其他 设备 上的 流。

根据 数据的 类型 分为:字节流字符流。

  • 字节流:以字节为 单位,读写数据的流。
  • 字符流:以字符为 单位,读写数据的流。

在这里插入图片描述
如果 数据 是 字符数据,也就是 字符串,文字内容啥的。就属于 字符流。

如果是 字节数据,那就是 字节流。一般 字节数据 都是 各种文件。二进制那种的。

但 实际上,我们都知道 一切数据 都是 二进制的。只是 解析的不一样罢了。即 一切的 数据 在我们 Java 里 都可以 被当作 字节来处理。比如 文本内容、突破、视频 等等。而 字符流 只是 被 进行的 二次封装,更加 方便 我们 输入输出 字符数据。才发明的 字符流。


2.2 OutputStream 和 FileOutputStream

OutputStream 是一个 抽象类是 表示 字节输出流 的 所有类的 超类,将指定 的 字节信息 写出 到 目的地,它 定义了 字节输出流 的 基本 共性 功能 方法。

close() 关闭和释放 输出流

flush() 强制性 刷新 输出流,让其在 缓冲区里的 数据 直接 被写出。因为 正常情况下,都是 满了 缓冲区后 才会 进行 输出的。这样就会 出现假死现象。用 flush() 刷新下就好了。

write() 从指定的 字节 数组写入 len 个 字节,从 偏移量 off (起始位置) 开始 输出到 这个输出流。一旦 数据 被 输出到 某个 对象的 输出流里,这个数据 就会 流入 这个 对象!实现 写入 或 输出的功能。

抽象类 注定 是为了 真正有实际意义的 类 做铺垫的,比如 FileOutputStream 对 文件 进行 输出操作。 你像以前 我们也 接触过 socketOutputStream 这些其实 都是 实现类,使用起来 都 大同小异。

FileOutputStream 类 是 文件输出流,用于 将 数据 写出 到 文件。它是 OutputStream 非常经典的 实现类,它 有两个 构造方法。它 甚至 可以 在 该 文件 不存在的时候,创建该文件。然后 再 进行 输出操作。

  • FileOutputStream(File file) 创建文件输出流 以 写入的方式 指定 File 对象 那个 文件。
  • FileOutputStream(String name) 创建文件输出流 以 写入的方式 指定 File 对象 那个 文件。
    public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream("text.txt");

        // 既然 是 写 字节,那么 就 建立 一个 字节数组呗。
        byte[] bytes = "我是一个字符串".getBytes();

        fileOutputStream.write(bytes,0,bytes.length);
    }

在这里插入图片描述
字节嘛,当然 字符 也可以 输出了。本质都是字节!

剩下的 输出类,即使 你遇到了,也是 大同小异的。主要是 你得 理解 输入 输出的 逻辑。只要理解了 逻辑 和 使用的 步骤 基本上 就没问题了!


2.3 InputStream 和 FileInputStream

InputSream 抽象类 是表示 字节输入流 的 所有类的 超类,可以读取 字节信息 到 内存中。它 定义了 字节输入流 的 基本 共性 功能 方法。

  • close() 关闭 和 释放 输入流
  • read() 从 输入流 读取数据的 下一个字节
  • read(byte[] bytes) 从输入流 中 读取一些 字节数,并将 它们 存储 到 字节 数组 bytes 中。并且 还会 返回 读取 的 字节长度 len!这个 最常用!
  • read(byte[] bytes,int off,int len) 从输入流 中 读取一部分 字节数,并将 它们 存储 到 字节 数组 bytes 中。并且 还会 返回 读取 的 字节长度 len!这个 最常用!

FileInputStream 是 InputStream 的一个 实现类,主要是 读取 文件的 数据 到 内存中。

  • FileInputStream(File file) 通过打开 文件,建立连接。来 获取 该 文件的 输入流。
  • FileInputStream(String name) 通过打开 文件,建立连接。来 获取 该 文件的 输入流。

那么 FileinputStream 肯定 也有 read() 读的 方法呀,所以 获取到 文件的 输入流 后,我们 就可以 读取 该 文件的数据了。

FileInputStream fileInputStream = new FileInputStream("text.txt");
        int len = fileInputStream.read(bytes);
        System.out.println(new String(bytes,0,len));

在这里插入图片描述
常规并且稳定的写法:(自建缓冲区数组,while 循环慢慢的 来)

 int len = 0;
        FileInputStream fileInputStream = new FileInputStream("text.txt");
        FileOutputStream fops = new FileOutputStream("text1.txt");

        while((len = fileInputStream.read(bytes)) != -1){
            fops.write(bytes,0,len);//bytes 1024 个字节
        }

在这里插入图片描述


2.4 实现 复制 图片

既然 我们 已经 知道了 文件的 IO,那么 图片 也算是文件。我们只要 实现了 图片的 IO 不就相当于 学会了 所有文件的 IO 了嘛。确实是这样的!

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

public class 图片复制 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\muqua\\Desktop\\MuQuanyu\\个人信息\\头像.jpg");

        FileOutputStream fos = new FileOutputStream("头像.jpg");

        byte[] bytes = new byte[1024];
        int len = 0;

        while((len = fis.read(bytes)) != -1 ){
            fos.write(bytes,0,len);
        }

        fos.close();
        fis.close();

    }
}

在这里插入图片描述


2.5 字符流

为什么有字符流呢?举一个 最 好理解的例子。我们的 汉字每一个 占 两个字节。英文和数字 每一个 占 一个字节。那么如果 我们 按照 字节流来读写的话 就不是那么的方便了。 可能 读 英文和 数字的时候 按照 一个字节一个字节 计算的, 但是到了 中文的时候 就得是 两个字节来计算。这 就会 很麻烦。而且 比如 你定义 一个 byte[10] 那么 你来回 读取 一段字符,不一定就 是按照 你想的那样读取的完整的。可能到了 汉字那里,就 按照 一个字节 读取了,那不就把 字 给砍了一半嘛。也就是出现了 乱码现象!!


2.6 Writer 和 FileWriter

Writer 抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节输出流的基本共性功能方法。

write(unicode编码/ascii编码) 写入单个字符

write(char[] cbuf) 写入一个 字符数组

write(char[] cbuf,int off,int len) 写入字符数组的 一部分,从 偏移 off 开始,写 len 个 字符。

write(String str) 写入字符串

write(String str,int off,int len) 写入字符串的 一部分,从 偏移 off 开始,写 len 个 字符。

flush() 刷新 该流 的 缓冲区

close() 关闭 和 释放 此 流,但最好是 将其 刷新 一下 再 关闭。

FileWriter 类 是 写出 字符到 文件里的 实现类,构造时使用系统默认的字符编码和默认字节缓冲区。

FileWriter(File file) 创建 一个 新的 FileWriter,给定要 写入的 File 对象。

FileWriter(String name) 创建 一个 新的 FileWriter,给定要 写入的 File 文件名称。

    public static void main(String[] args) throws IOException {
        Writer fw = new FileWriter("test.txt");
        fw.write("我是一段 字符串!");
        fw.flush();
        fw.close();
    }

2.7 Reader 和 FileReader

**Reader 抽象类 是 表示 用于 读取 字符流的 所有类的超类,可以 读取字符信息到 内存中。它 定义了 字符输入流的 基本 共性 功能方法。 **

close() 关闭 此 流 并 释放 与 此流 相关联 的 任何 系统 资源。

read() 从 输入流 读取的 一个 字符

read(char[]) 从输入流 中 读取 一些字符,并把它们 存储到 字符数组里。

read(char[],int off,int len) 从输入流 中 读取 一部分字符,并把它们 存储到 字符数组里。

为啥 没有 存储到 String 里面的呢。主要是因为 数据的长度 不可定,我们可以用 字符数组来限制每次读取的字符长度,但是 String 是真心 不合适。所以 就没设计这种 方法。

FileReader 类 是 读取 字符文件的 类。构造 时 使用 系统默认的 字符编码 和 默认 字节缓冲区。

FileReader(File file) 创建一个 新的 FileReader,给定 要 读取的 File 对象。

FileReader(String name) 创建一个 新的 FileReader,给定 要 读取的 File 文件 名称。

import java.io.*;

public class WriterTest {
    public static void main(String[] args) throws IOException {
        Writer fw = new FileWriter("test.txt");
        fw.write("我是一段 字符串!");
        fw.flush();
        fw.close();
        Reader fr = new FileReader("test.txt");
        char[] chars = new char[6];
        int len = 0;

        while((len = fr.read(chars)) != -1){
            System.out.print(new String(chars,0,len));
        }
        fr.close();

    }
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值