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字符输出流

相关推荐
乐橙开放平台2 分钟前
老旧社区双通道笔记:周界 hoveringAlarm / aiPerArea + 电梯 aiNonVehDetect,一套 callback 做 24h 防护
笔记·物联网·音视频·智能家居
一木 之林6 分钟前
五、C++新特性、关键字与编译原理
java·jvm·算法
han_hanker9 分钟前
新手公司项目实战
java·maven
想要成为老金高手15 分钟前
Kubernetes 实战笔记(一):Pod 管理与 kubectl 核心命令全解
笔记·容器·kubernetes
vHelios15 分钟前
【电商项目】商品搜索开发复盘(3):搜索与封装实现逻辑思考与编写
java
程序员麻辣烫18 分钟前
反曲弓射箭笔记
笔记·生活
AI人工智能+电脑小能手34 分钟前
大白话说Java设计模式-37-中介者模式(源码剖析篇)
java·设计模式·线程池·中介者模式·源码分析·executor·applicationeventmulticaster
焦虑的说说1 小时前
虚拟线程浅析
java
摇滚侠1 小时前
《SpringBoot 3:入门与应用实战》第 7 章 AOP 思想与实现 阅读笔记 13
java·spring boot·笔记