IO流——字符集

一、IO流的体系

1.1 字符集

1.1.1 计算机的存储规则

① ASCII字符集

ASCII码对应的最大数字是127,一共是0-127,128个字符。一个字节最多可以表示256的数据。所以可以得出一个结论:存储英文,一个字节足以。

编码:把字符集当中查询到的数据,按照一定的规则进行计算,变成真实的能存储在硬盘当中的二进制数据。解码就是相反的过程。

② GBK字符集

底层如何区分中英文:

③ Unicode字符集

不管是一个字母还是别的字符,UTF-16统一用16个bit,而UTF-32是用32个bit。这在某些字符的存储上十分浪费空间。

后来出现的UTF-8就采用了分门处理的方式进行了优化。

1.2.1 为什么会有乱码?

只读取了片段,解码成不符合字符集规则的数据出现乱码。

原因二:编码和解码的方式不一致。

因为拷贝的时候,数据源的数据没有丢失,拷贝的一样,而且目的地编码方式跟数据源保持一致就不会出现乱码。

1.3.1 Java中编码和解码的代码实现

java 复制代码
package com.lkbhua.IO;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Arrays;

public class demo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        /*  Java中编码的方式:
                public byte[] getBytes()                        使用默认方式进行编码
                public byte[] getBytes(String charsetName)      使用指定方式进行编码

            Java中解码的方式:
                String(byte[] bytes)                            使用默认方式进行解码
                String(byte[] bytes, String charsetName)        使用指定方式进行解码
         */

        // 1、编码
        String str = "Ai中国";
        byte[] bytes = str.getBytes(); // GBK E: 1 C: 2
        System.out.println(Arrays.toString(bytes));
        // [65, 105, -42, -48, -71, -6]

        // 2、指定编码
        byte[] bytes1 = str.getBytes("UTF-8");
        System.out.println(Arrays.toString(bytes1));
        // [65, 105, -28, -72, -83, -27, -101, -67]

        // 3、解码
        String str1 = new String(bytes);
        System.out.println(str1);
        // Ai中国

        // 4、指定解码
        String str2 = new String(bytes1, "UTF-8");
        System.out.println(str2);
        // Ai中国
    }
}

1.2 字符流

对于原因二:编码和解码方式不统一的情况我们可以通过统一编码方式进行很好的解决。但是原因一怎么解决呢?字符流可以很好的解决。

1.2.1 FileReader字符输入流

空参的read()方法:

java 复制代码
package com.lkbhua.IO.FileReaderDemo;

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

public class demo1 {
    public static void main(String[] args) throws IOException {
        /*
            第一步: 创建对象
            public FileReader(File file)            创建字符输入流关联本地文件
            public FileReader(String fileName)      创建字符输入流关联本地文件

            第二步: 读取数据
            public int read()                       读取数据,读到末尾返回-1
            public int read(char[] cbuf)            读取多个数据,读到末尾返回-1

            第三步: 释放资源
            public void close()                    释放资源
        */

        // 1、创建对象并关联本地文件
        FileReader fr = new FileReader("lkb04-File&IOCode\\a.txt");
        // 2、读取数据 read()
        // 细节1: 默认是一个字节一个字节读取,如果遇见中文就会读取多个(GBK:2,UTF-8:3)
        // 细节2: 在读取之后,方法底层还会解码转成十进制。
        //       最终将这个十进制作为返回值
        //       这个十进制的数据也表示在字符集上的数字
        // 比如是English: 0110 0001
        //      read方法读取进行解码: 97
        // 比如是Chinese: 1100 1001 1000 1001
        //      read方法读取进行解码: 20989
        int ch;
        while((ch = fr.read()) != -1){
            System.out.print((char)ch);
        }
        // 3、释放资源
        fr.close();
    }
}

带参的read()方法:

java 复制代码
package com.lkbhua.IO.FileReaderDemo;

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

public class demo2 {
    public static void main(String[] args) throws IOException {
        /*
            第一步: 创建对象
            public FileReader(File file)            创建字符输入流关联本地文件
            public FileReader(String fileName)      创建字符输入流关联本地文件

            第二步: 读取数据
            public int read()                       读取数据,读到末尾返回-1
            public int read(char[] cbuf)            读取多个数据,读到末尾返回-1

            第三步: 释放资源
            public void close()                    释放资源
        */

        // 1、创建对象
        FileReader fr = new FileReader("lkb04-File&IOCode\\a.txt");
        // 2、读取数据
        // read(chars): 读取数据、解码、强壮三步合并了,把强转之后的字符放到数组当中
        // 空参的read + 强转类型转换
        char[] chars = new char[2];
        int len;
        while ((len = fr.read(chars)) != -1){
            // 把数据中的字符串进行打印
            System.out.print(new String(chars, 0, len));
        }
        // 3、释放资源
        fr.close();
    }
}

1.2.2 FileWrtie字符输出流

相关推荐
cfm_291413 分钟前
单例模式详解
java
我叫张土豆23 分钟前
本体论、DDD、SDD、TDD:AI 编程时代的四层认知栈
java·人工智能
白远山35 分钟前
家政服务家政社区派单实战:调度系统架构设计与实现指南
java·开发语言·小程序·架构·需求分析
海南java第二人41 分钟前
从诞生到回收:JVM对象生命周期与垃圾回收全链路解析
java
SL_staff1 小时前
JVS-Logic:从页面配置工具到企业级业务逻辑中枢的技术演进
java·算法·全栈
DevRay1 小时前
Java 21虚拟线程深度实战:告别线程池焦虑,百万并发吞吐量直接翻倍(原理+代码+避坑)
java·开发语言
forestsea1 小时前
从零构建 Java 智能体 RAG 系统:Milvus 向量数据库实战指南
java·数据库·milvus
lifewange1 小时前
VSCode怎么运行java
java·ide·vscode
用户094248568031 小时前
第10章:OpenJDK异常体系、栈轨迹与错误诊断入门
java·jvm
醉颜凉2 小时前
Java 必看:如何彻底避免 HashMap 多线程死循环问题?
java·开发语言