【从零开始学Java | 第三十六篇】字符流

目录

前言

一、字符集(ASCII、GBK、Unicode)

二、Java中编码和解码的方式

1.Java中编码的方法

2.Java中解码的方式

3.案例

三、FileReader

1.空参read方法

2.带参read方法

四、FileWriter

1.构造方法

2.成员方法

3.案例

总结


前言

在上一篇我们学习了字节流,但是字节流在处理纯文本(尤其是包含中文的文本)时,纯粹的字节流很容易引发乱码问题,字符流的出现让我们可以解决中文乱码的问题。

一、字符集(ASCII、GBK、Unicode)

  • ASCII :美国人发明的,只包含英文字母、数字和符号。一个字符占 1 个字节

  • GBK中国人 为了显示汉字发明的标准。在这个标准里,英文占 1 个字节,中文占 2 个字节

    • GBK字符集完全兼容ASCII字符集;

    • 一个英文占一个字节,二进制第一位是0;

    • 一个中文占两个字节,二进制高位的第一个字节是1。

  • Unicode (UTF-8)⭐⭐⭐:万国码,目前互联网最通用的标准。在 UTF-8编码下,英文占 1 个字节,中文占 3 个字节

二、Java中编码和解码的方式

1.Java中编码的方法

String类中的方法 说明
public byte\[\] getBytes() 使用默认方式进行编码
public byte\[\] getBytes(String charsetName) 使用指定方式进行编码

2.Java中解码的方式

| String类中的方法 | 说明 |
| String (byte\[\] bytes) | 使用默认方式进行解码 |

String (byte\[\] bytes, String charsetName) 使用指定方式进行解码

3.案例

java 复制代码
public class Test {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //编码
        String str1 = "你好Java";
        byte[] bytes1 = str1.getBytes();
        System.out.println(Arrays.toString(bytes1));

        byte[] bytes2 = str1.getBytes("GBK");
        System.out.println(Arrays.toString(bytes2));

        //解码
        String str2 = new String(bytes1);
        System.out.println(str2);

        String str3 = new String(bytes2);
        System.out.println(str3);
    }
}

运行结果:

第一行使用UTF-8,对应三个字节为一个中文,正数一个字节为一个英文

第二行使用GBK,对应两个字节为一个中文,正数一个字节为一个英文

三、FileReader

为了解决字节流读取文本的痛点,Java 推出了字符流。

核心公式:字符流 = 字节流 + 字符集(编码表)

字符流在底层依然是在搬运字节,但它非常聪明:它会根据指定的默认操作系统的环境编码,通常是 UTF-8,自动判断读取几个字节拼成一个完整的字符。遇到英文读 1 个,遇到中文读 3 个,绝不劈开汉字。

核心流程:

①创建字符输入流对象

构造方法 说明
public FileReader(File file) 创建字符输入流关联本地文件
public FileReader(String pathName) 创建字符输入流关联本地文件

细节:如果文件不存在,则直接报错。

②读取数据

| 成员方法 | 说明 |
| public int read() | 读取数据,读到末尾返回-1 |

public int read(**char\[\]**buffer) 读取多个数据,读到末尾返回-1

③释放资源

1.空参read方法

java 复制代码
public class Test {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("src\\a.txt");

        int ch;
        while((ch = fr.read()) != -1){
            System.out.print((char)ch);
        }
        fr.close();
    }
}

运行结果:

2.带参read方法

注意:要创建char类型的数组。

java 复制代码
public class Test02 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("src\\a.txt");

        char[] chars = new char[2];//一次读取两个字符

        int len;

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

        fr.close();
    }
}

运行结果:

总结

1、空参read方法,只读取到字符的十进制,需要我们自己来进行一次强制类型转换为char。

2、带参read方法,相当于空参read方法加上强制类型转换。

四、FileWriter

1.构造方法

构造方法 说明
public FileWriter(File file) 创建字符输出流关联本地文件
public FileWriter(String pathName) 创建字符输出流关联本地文件
public FileWriter(File file, boolean append) 创建字符输出流关联本地文件,续写
public FileWriter(String pathName, boolean append) 创建字符输出流关联本地文件,续写

2.成员方法

成员方法 说明
void write(int c) 写出一个字符
void write(String str) 写出一个字符串
void write(String str, int off, int len) 写出一个字符串的一部分
void write(char\[\] cbuf) 写出一个字符数组
void write(char\[\] cbuf, int off, int len) 写出一个字符数组的一部分

3.案例

java 复制代码
public class FileWriterDemo01 {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("src\\b.txt");

        fw.write("Unicode (UTF-8):万国码,目前互联网最通用的标准。\n" +
                "在 UTF-8 编码下,英文占 1 个字节,中文占 3 个字节。");

        fw.close();
    }
}

写入结果:

总结

  • 图片、视频、音频、压缩包 ➡️ 字节流 (FileInputStream / FileOutputStream)

  • Word、Excel ➡️ 字节流 (它们不是纯文本,是富文本格式)

  • TXT、Java 源码、XML、JSON 等纯文本 ➡️ 字符流 (FileReader / FileWriter)

💕❤️😘

相关推荐
charlie1145141915 小时前
RK3506B: buildroot:出一份正规的最小 rootfs
开发语言·嵌入式·开源项目·rk3506b
jason成都5 小时前
GNSS-QC 数据清洗功能全面增强|滑坡监测实测验证,适配 rtklib_java 高精度解算链路
java·gnss
前端工作日常5 小时前
我学习到的Java概念
java·后端
卓怡学长5 小时前
w263基于springboot + vue 健康饮食管理系统
java·数据库·vue.js·spring boot·spring·intellij-idea
r_oo_ki_e_5 小时前
Java反射机制学习笔记
java·笔记·学习
Byron Loong5 小时前
【c#】Bitmap释放之 大象与蚊子
开发语言·c#
九皇叔叔5 小时前
RHEL9.8 配置本地镜像仓库
android·java·缓存
范什么特西5 小时前
苍穹外卖体会
java
Nontee5 小时前
数据类型与包装类 — 一个新手学Java的数据类型笔记
java·笔记·python
音符犹如代码5 小时前
Java动态线程池:避坑原生线程池,吃透Dynamic-TP,手写一个Demo
java·开发语言