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

💕❤️😘

相关推荐
sunshine22 girl18 分钟前
Java学习六 Java常见API-1-Radom随机数
java·开发语言·学习
可乐鸡翅yeah_22 分钟前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
潼心1412o38 分钟前
C++初阶(长期更新)第6讲:类和对象(下)
开发语言·c++·算法
wangbing11251 小时前
使用jps jstack排查系统问题
java
夜晚回家1 小时前
Python 零基础入门 | 输入的数字为什么不能直接算
开发语言·python
时间的拾荒人1 小时前
Qt 事件机制全解析:从事件处理到事件过滤器
开发语言·qt·面试
于指尖飞舞1 小时前
java面试题总结
java·开发语言
ZealSinger2 小时前
LangChain4j用AiServices拼Tool
java·rag·ai智能体·langchain4j
vx_Biye_Design2 小时前
springboot高校选课系统82776-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·课程设计·express
zhangzeyuaaa2 小时前
深入理解 Ruby 运算符:本质、分类、坑点与重载实战
开发语言·前端·ruby