Skip to content

Java IO - 02 前置知识之字符集与字符编码

本文主要介绍字符集与字符编码。

1. 字符集

字符集是一组字符的集合,它定义了可以使用的字符范围。字符集中的每个字符都有一个唯一的编号,称为码点(Code Point)。有以下特点:

  • 唯一性:字符集中的每个字符都有一个唯一的编号。
  • 范围:字符集可以包含字母、数字、标点符号、符号等。

常见的字符集如下:

  • ASCII:美国信息交换标准代码(American Standard Code for Information Interchange),包含 128 个字符,包括英文字母、数字和一些控制字符。

  • Unicode :统一码,是一个更庞大的字符集,涵盖全球几乎所有文字(如中文、阿拉伯文、表情符号),每个字符有唯一码点。

    Unicode网站:https://home.unicode.org/

2. 字符编码

虽然每个字符在字符集中有唯一的编号,但是存储在计算机中需要将其转换为二进制形式,如何将码点转换为二进制,称为字符编码。常见的字符编码如下:

  • ASCII:每个字符用一个字节表示,范围是 0x00 到 0x7F。
  • UTF-8:一种变长编码,用 1 到 4 个字节表示一个字符。
  • UTF-16:用 2 个字节表示一个字符,对于超出 16 位的字符,用 4 个字节表示。
  • GBK:用 2 个字节表示一个字符,主要用于简体中文。

这里主要介绍一下UTF-8编码:UTF-8 是一种用于Unicode字符集的变长编码,将字符编码为1-4个字节,并且兼容ASCII编码。

码点范围字节数字节格式(二进制)
U+0000U+007F10xxxxxxx
U+0080U+07FF2110xxxxx 10xxxxxx
U+0800U+FFFF31110xxxx 10xxxxxx 10xxxxxx
U+10000U+10FFFF411110xxx 10xxxxxx 10xxxxxx 10xxxxxx

例如,✅的码点为U+2705,转换为二进制为:

00100111 00000101

我们需要三个字节才能编码完成,按照UTF-8的规则,编码完成后的二进制格式如下:

11100010 10011100 10000101

3. 在Java中编码与解码

在String类中,提供了如下的方式进行编码与解码:

  • byte[] getBytes(String charsetName):使用指定的字符集将字符串编码为字节数组;
  • String(byte[] bytes, String charsetName):通过指定的字符集,将字节数组解码为字符串;
java
String str = "你好";
byte[] bytes = str.getBytes("UTF-8");
System.out.println(bytes.length);  // 6

byte[] bytes1 = str.getBytes("GBK");
System.out.println(bytes1.length);  // 4
java
String str = "你好";
byte[] bytes = str.getBytes("UTF-8");        

String s1 = new String(bytes, "UTF-8");
System.out.println(s1); // 你好

String s2 = new String(bytes, "GBK");
System.out.println(s2);  // 浣犲ソ

可以看出用不同的字符编码方式编解码会造成乱码。