字符编码

文件的编码

编码

概念:规定每个“字符”采用一个字节还是多个字节来存储以及用哪些字节来存储。(通俗的说就是把“字符”转化成“字节”)

扫盲区:

  1. 位:(bit)
  • 这里说的位就是指的二进制位了,也就是说的0或者1。他们都可以表示一位
  1. 字节:(byte)
  • 计算机存储数据的一个单位
  • 组成:由8个0或1组成也就是我们所谓的一个byte(字节)
  • 实际上在Java中,byte就是一个0-255之间的整数
  • 举个栗子:0x01, 0x45, 0xFA,.....
  1. 字符:
  • 人们所使用的记号,抽象意义上的一个符号。
  • 通俗的说就是我们平时看到的一切字母、符号、中文、法文、日文等等。c是个字符、中也是个字符。
  • 一个字符的大小(也就是其所占的二进制位)是由编码规则决定的,
  • 举个栗子:1', '中', 'a', '$', '¥', ……

要知道的:在计算机内部采用的是二进制进行存储,但是作为人呢,自然有自己的语言。因此为了让计算机能够看能我们的语言,就要采用一定的编码然后在发给计算机;计算机如果想要将信息呈现给我们看就要进行相应的解码。

  • 字符-->字节(编码)encode
  • 字节-->字符(解码)decode

字符集

定义: 将我们使用的字母、汉字、符号收入标准中;相当于一本大字典,这个字典里面有常用的字符相对应的二进制码。

“字符集”和“编码”一般都是同时制定的。因此,平常我们所说的“字符集”,比如:ISO-8859-1、UTF-8、GB2312, GBK, JIS 等,除了有“字符的集合”这层含义外,同时也包含了“编码”的含义。

编码格式 英文字符(所占字节数) 汉字(所占字节数)
ISO-8859-1 1 1
ASCII 1 2
GBK 1 2
GB2312 1 2
UTF-8 1 3/4
UTF-16 4 2/4

字符编码发展

系统内码 编码标准 说明 系统
阶段一 ASII ISO-8859-1 胚胎级别的编码方式(最原始的啦)只支持英语,其它语言不能够在计算机上存储和显示 DOS
阶段二 ANSI GB2312,GBK, JISGB2312,BIG5,Shift_JIS, 为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。比如:汉字 '中' 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。不同的国家和地区制定了不同的标准,由此产生了等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码 中文 DOS,中文 Windows 95/98,日文 Windows 95/98
阶段三 UNICODE(国际化) UTF-8,UTF-16, UnicodeBig …… 为了使国际间信息交流更加方便,国际组织制定了 UNICODE 字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。 Windows NT/2000/XP,Linux,Java

常用的字符编码简介

  1. ASCII(1字母1字节占8位)

    问题:计算机只识别0或1,不识别符号

    解决:既然不识别那就造一个”字典“给翻译成二进制代码。由于这个法子是美国人想到的所以计算机刚开始只支持英语,其它语言不能够在计算机上存储和显示。一个字母需要一个字节表示,也就是说占8位。这样的话有256种0和1的组合方式,可以表示256个不同的字母。对于,英文而言就绰绰有余了。

  2. GB2312(1字母1字节;1汉字2字节)

    问题:显然,美国人在设计ASCII码的时候没有考虑到遥远的东方,存在博大精深的文化。新华字典里面的汉字有多少个?显然256是远远不够的!那平方呢?65535?够了吧?还不够?

    解决:于是就发明了GB2312这些汉字编码,典型的用2个字节来表示绝大部分的常用汉字,英文还是和ASCII保持一致占一个字节。

  3. UNICODE(1字符多字节取决于编码格式)

    问题:这下各用各的字符集编码,这世界咋统一?俄国人发封email给中国人,两边字符集编码不同,尼玛显示都是乱码啊。

    解决:于是就发明了unicode,将世界上所有的符号都纳入其中,每一个符号都给予一个独一无二的编码,现在unicode可以容纳100多万个符号,每个符号的编码都不一样,这下可统一了,所有语言都可以互通,一个网页页面里可以同时显示各国文字。

    这里就说到一个网络上经常出现的一个问题,UNICODE编码里面,一个汉字占几位的问题。很多老程序员会这么说:“一个汉字占两个字节!其实,很多时候,汉字占几个自己完全取决于编码格式。编码格式也不难写,因此对于汉字的编码有多种说法:ubuntu12.04里面一个汉字是三个字节!就是说,在unicode编码下,一个汉字可能是2个字节,也可能是3个或者是4个字节。“UNICODE 字符集”包含了各种语言中使用到的所有“字符”。用来给 UNICODE 字符集编码的标准有很多种,比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig 等。

  4. utf8(1字母1字节;1汉字1-4字节)

    问题:unicode虽然统一了全世界字符的二进制编码,但没有规定如何存储啊,亲。x86和amd体系结构的电脑小端序和大端序都分不清,别提计算机如何识别到底是unicode还是acsii了。如果Unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,文本文件的大小会因此大出二三倍,这对于存储来说是极大的浪费。这样导致一个后果:出现了Unicode的多种存储方式。

    解决:即UTF-8不是固定字长编码的,而是一种变长的编码方式。它可以使用1~4个字节表示一个符号(注意”符号“中英文都有可能),根据不同的符号而变化字节长度。这是种比较巧妙的设计,如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。因此在utf8编码格式下,英文字母占一个字节,和ascii完全相同。汉字或者是其他字符占1-4个字节。

练习

	/**
	 * 
	 *@描述:字符的编码(字符-->字节)
	 * @param args
	 * @throws UnsupportedEncodingException 
	 */
	public static void main(String[] args) throws UnsupportedEncodingException {
		String msg = "相信自己";
		//默认的是使用工程的编码格式
		byte[] datas = msg.getBytes();
		System.out.println(datas.length);
		//将msg按照指定的字符集进行编码
		byte[] datas1 = null;
		datas1 = msg.getBytes("UTF-8");
		System.out.println(datas1.length);
	}
/**
 * 
 * @描述:解码(字节-->字符)
 * 
 *  String(byte[] bytes) 
		通过使用平台的默认字符集解码指定的字节数组来构造新的 String 。  
	String(byte[] bytes, Charset charset) 
		构造一个新的String由指定用指定的字节的数组解码charset 。  
	String(byte[] bytes, int offset, int length) 
		通过使用平台的默认字符集解码指定的字节子阵列来构造新的 String 。  
	String(byte[] bytes, int offset, int length, Charset charset) 
		构造一个新的String通过使用指定的指定字节子阵列解码charset 。 
	String(byte[] bytes, int offset, int length, String charsetName) 
		构造一个新的 String通过使用指定的字符集解码指定的字节子阵列。  
	String(byte[] bytes, String charsetName) 
		构造一个新的String由指定用指定的字节的数组解码charset 。  
 */
public class contentDecode {
	public static void main(String[] args) throws UnsupportedEncodingException {
		String msg = "相信自己!";
		//使用utf-8进行编码
		byte[] datas = msg.getBytes("utf-8");
		System.out.println("utf-8编码后的结果:"+datas);
		//使用utf-8进行解码
		String info = new String(datas,"utf-8");
		System.out.println("utf-8解码后的结果:"+info);
		String info1 = new String(datas,"iso-8859-1");
		System.out.println("iso-8859-1解码后的结果:"+info1);
		System.out.println(datas.length);
		String info2 = new String(datas,0,datas.length-3,"utf-8");
		System.out.println(info2);
	}
}
原文地址:https://www.cnblogs.com/lomon6/p/10764777.html