【从零开始学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)

💕❤️😘

相关推荐
旖旎夜光4 小时前
【C++ 基础入门】C++11 新特性(中):右值引用、移动语义与完美转发
开发语言·c++·笔记·学习
Lansonli5 小时前
大数据Spark(八十八):Spark任务资源之Standalone集群测试
java·服务器·spark
ShineWinsu5 小时前
对于Qt:QTabWidget常见属性的解析
开发语言·数据库·c++·qt·浏览器·qtabwidget·标签页
budingxiaomoli5 小时前
Spring AOP
java·spring·java-ee
特立独行的猫A5 小时前
Ionic + 仓颉语言的 cj-tauri 开发框架实战:开发精美移动端 APP
java·后端·python
nice_lcj5205 小时前
LRU 缓存入门:它是什么、怎么用、面试怎么手写
java·数据结构·缓存·面试·lru
普通人65 小时前
WebGL与WebGPU入门指南
开发语言·webgl·1024程序员节
꧁细听勿语情꧂6 小时前
直接选择排序,堆排序,冒泡排序,递归快速排序、hoare版本、挖坑法、lomuto前后指针,非递归快速排序
c语言·开发语言·数据结构·算法
SomeOtherTime6 小时前
Rust集合(AI回答)
开发语言·后端·rust
文丑颜不良啊6 小时前
LeetCode2741~2760题目解析
java·leetcode