Java基础 第四节 第十七课

举报
我是小白呀iamarookie 发表于 2021/09/11 02:13:43 2021/09/11
【摘要】 转换流 字符编码和字符集字符编码字符集ASCII 字符集ISO-8859-1 字符集GBxxx 字符集Unicode 字符集 编码引出的问题InputStreamReader 类构造方法...

字符编码和字符集

字符编码

字符编码 Character Encoding: 就是一套自然语言的字符与二进制数之间的对应规则.

计算机中存储的信息都是用二进制数表示的, 而我们在屏幕上看到是数字, 英文, 标点符号, 汉字等字符是二进制数转换之后的结果. 按照某种规则显示出来, 称为解码. 比如说, 按照 A 规则存储, 同样按照 A 规则 解析, 那么就能显示正确的文本符号. 反之, 按照 B 规则解析, 就会导致乱码现象.

字符集

字符集 Charset: 也叫编码表. 是一个系统支持的所有字符的集合, 包括各个国家文字, 标点符号, 图形符号, 数字等.

计算机要准确的存储和识别各种字符集符号. 需要进行字符编码, 一套字符集必然至少有一套字符编码. 常见字符集有 ASCII 字符集, GBK 字符集, Unicode 字符集等.

在这里插入图片描述
可见, 当指定了编码, 它所对应的字符集自然就指定了, 所以编码才是我们最终要关心的.

ASCII 字符集

ASCII, 美国信息交换标准代码 (American Standard Code for information Interchange) 是基于拉丁字符的一套电脑编码系统, 用于显示现代英语, 主要包括控制字符 (回车键, 退格, 换行键等) 和可显示字符 (英文大小写字符, 阿拉伯数字和西文符号).

基本的 ASCII 字符集, 使用 7 位 (bits) 表示一个字符, 共 128 字符. ASCII 的扩展字符集使用 8 位 (bits) 表示一个字符, 共 256 字符, 方便支持欧洲常用字符.

ISO-8859-1 字符集

拉丁码表, 别名 Latin-1, 用于显示欧洲使用的语言, 包括荷兰语, 丹麦语, 德语, 意大利语, 西班牙语等.

ISO-5559-1 使用单字节编码, 兼容 ASCII 编码.

GBxxx 字符集

GB 就是国标的意思, 是为了显示中文而设计的一套字符集:

  • GB2312: 简单中文码表. 一个小于 127 的字符的意义与原来相同. 但是两个大于 127 的字符连在一起时, 就表示一个汉字, 这样大约可以组合了包含 7000 多个简体汉字. 此外数学符号, 罗马希腊的字母, 日文的假名都编写进去了. 连在 ASCII 里本来就有的数字, 标点, 字母都统统重新编了两个字节长的编码, 这就是常说的 “全角” 字符. 而原来在 127 号一下的那些就叫 “半角” 字符了
  • GBK: 最常用的中文码表. 是在 GB2312 标准基础上的扩展范围, 使用了双字节编码方案. 共收录了21003 个汉字, 完全兼容 GB2312 标准, 同时支持繁体汉字以及日韩汉字等
  • GB18030: 最新的中文码表. 收录汉字 70244 个. 采用多字节编码, 每个子可以由 1 个, 2 个或 4 个字节组成. 支持中国国内少数名族的文字, 同时支持繁体汉字以及日韩汉字等

Unicode 字符集

Unicode 编码系统为表达任意语言的任意字符而设计. 是业界的一种标准, 也称为统一码, 标准万国码. Unicode 最多使用 4 个字节的数字来表达每个字母, 符号, 或者文字. 有三种编码方案, UTF-8, UTF-16 和 UTF-32. 最多常用的 UTF-8 编码.

UTF-8 编码, 可以用来表示 Unicode 标准中任何字符. 它是电子邮件, 网页及其他存储或传送文字的应用中, 优先采用的编码. 互联网工程工作小组 (IETF) 要求所有的互联网协议都必须支持 UTF-8 编码. 所以, 我们开发 Web 应用, 也要使用到 UTF-8 编码. 它使用 1~4 个字节为每个字符编码, 编码规则:

  1. 128 个 US-ASCII字符, 只需要一个字节编码
  2. 拉丁文等, 需要两个字节编码
  3. 大部分常用文字 (含中文), 使用三字节编码
  4. 其他极少使用的 Unicode 辅助字符, 使用四字节编码

编码引出的问题

在 IDEA 中, 使用 FileReader 读取项目中文本文件. 由于 IDEA 的设置, 都是默认的 UTF-8 编码, 所以没有任何问题. 但是, 当读取 Windows 系统中创建的文本文件时, 由于 Windows 系统的默认编码是 GBK 编码, 就会出现乱码.

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

public class Test {
    public static void main(String[] args) throws IOException {
        FileReader fileReader = new FileReader(""E:\\File_GBK.txt");
        int read;
        while ((read = fileReader.read()) != -1) {
            System.out.print((char) read);
        }
        fileReader.close();
    }
}

输出结果:
���

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

那么我们如何读取 GBK 编码的文件呢?

InputStreamReader 类

转换流java.io.InputStreamReader, 是 Reader 的子类, 是从字节流到字符流的桥梁. 它读取字节, 并使用是定的字符集将其解码为字符. 它的字符集可以由名称指定, 也可以接受平台的默认字符集.

构造方法

InputStreamReader(InputStream in):
 创建一个使用默认字符集的字符流

InputStreamReader(InputStreamin, String): 
创建一个指定字符集的字符流

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

构造举例, 代码如下:

public static void main(String[] args) throws IOException {
        // 创建一个使用默认字符集的字符流
        InputStreamReader isr1 = new InputStreamReader(new FileInputStream("in.txt"));

        // 创建一个GBK字符集的字符流
        InputStreamReader isr2 = new InputStreamReader(new FileInputStream("in.txt"), "GBK");
    }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

指定编码读取

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {
    public static void main(String[] args) throws IOException {
        // 定义文件路径, 文件为GBK编码
        String FileName = "C:/Users/Windows/Desktop/GBK.txt";
        // 创建流对象, 默认UTF-8编码
        InputStreamReader isr_utf = new InputStreamReader(new FileInputStream(FileName));
        // 创建流对象, 指定GBK编码
        InputStreamReader isr_gbk = new InputStreamReader(new FileInputStream(FileName), "GBK");
        // 定义变量, 保存字符
        int read;
        // 使用默认编码读取, 会显示乱码
        while ((read = isr_utf.read()) != -1) {
            System.out.print((char) read);
        }
        // 释放资源
        isr_utf.close();
        // 换行
        System.out.println();

        // 使用指定编码字符流读取, 正常解析
        while ((read = isr_gbk.read()) != -1) {
            System.out.print((char) read);
        }
        // 释放资源
        isr_gbk.close();
    }
}

输出结果:
宀愮帇瀹呴噷瀵诲父瑙侊紝
宕斾節鍫傚墠鍑犲害闂汇��
姝f槸姹熷崡濂介鏅紝
钀借姳鏃惰妭鍙堥�㈠悰銆�
岐王宅里寻常见,
崔九堂前几度闻。
正是江南好风景,
落花时节又逢君。

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

OutputStreamWriter 类

转换流java.io.OutputStreamWriter, 是 Writer 的子类, 是从字符流到字节流的桥梁.使用指定的字符集将字符编写为字节. 它的字符集可以由名称指定, 也可以接受平台默认字符集.

构造方法

OutputStreamWriter(OutputStream in): 
创建一个使用默认字符集的字符流

OutputStreamWriter(OutputStream in, String charsetName):
 创建一个指定字符集的字符流

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

构造举例, 代码如下:

public static void main(String[] args) throws IOException {
        // 创建一个使用默认字符集的字符流
        OutputStreamWriter osw1 = new OutputStreamWriter(new FileOutputStream("out.txt"));
        
        // 创建一个GBK字符集的字符流
        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("out.txt"), "GBK");
    }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

指定编码写出

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class Test86 {
    public static void main(String[] args) throws IOException {
        // 定义文件路径
        String FileName1 = "C:/Users/Windows/Desktop/out1.txt";
        // 创建流对象, 默认UTF-8编码
        OutputStreamWriter osw1 = new OutputStreamWriter(new FileOutputStream(FileName1));
        // 写出数据
        osw1.write("你好");  // 保存为6个字节
        osw1.close();

        // 定义文件路径
        String FileName2 = "C:/Users/Windows/Desktop/out2.txt";
        // 创建流对象, 指定GBK编码
        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream(FileName2));
        // 写出数据
        osw2.write("你好");  // 保存为4个字节
        osw2.close();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

转换流理解图解

在这里插入图片描述

转换流是字节与字符间的桥梁!

练习: 转换文件编码

将 GBK 编码的文本文件, 准换为 UTF-8 编码文本文件.

案例分析

  1. 指定 GBK 编码的转换流, 读取文本文件
  2. 使用 UTF-8 编码的转换流, 写出文本文件

案例实现

import java.io.*;

public class Test87 {
    public static void main(String[] args) throws IOException {
        // 1. 定义文件路径
        String srcFile = "file_gbk.txt";
        String destFile = "file_utf8.txt";

        // 2. 创建流对象
        // 转换输入流, 指定GBK编码
        InputStreamReader isr = new InputStreamReader(new FileInputStream(srcFile), "GBK");
        // 转换输出流, 默认UTF-8编码
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(destFile));

        // 3. 读写数据
        // 定义数组
        char[] chars = new char[1024];
        // 定义长度
        int len;
        // 循环读取
        while ((len = isr.read(chars)) != -1) {
            // 循环写出
            osw.write(chars, 0, len);
        }

        // 4. 释放资源
        osw.close();
        isr.close();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

文章来源: iamarookie.blog.csdn.net,作者:我是小白呀,版权归原作者所有,如需转载,请联系作者。

原文链接:iamarookie.blog.csdn.net/article/details/111618622

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。