unicode字符集是几个字节表示一个字符?为啥需要utf-8?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unicode字符集是几个字节表示一个字符?为啥需要utf-8?相关的知识,希望对你有一定的参考价值。
一到四个字节表示一个字符,utf-8是一到两个字节,为了显示亚洲的等字符,比如中文,日文,所以要用unicode,utf-8是unicode的一种 参考技术A UTF-8, 都是由 1~4 字节组成的, 至于是多少字节, 是根据第一个字节的内容判断的。UNICODE 是一个超集, 内包含 UTF-8, UTF-16, UTF-32, UTF-8 最少 1 字节, UTF-16最少 2 字节, 如此类推。 全英文环境上,UTF-8 的优势是字节少, 相对传送效率高。
至于 VC++ UNICODE 编程, 类如 CString 等规定是 2 字节 16-bit 组成, 个人认为是一种误导与错误概念。 只不过微软公司 WINDOWS 独大, 可以自己歪曲标准, 这也是没有办法, 真有委屈承受, 或是改用 LINUX。 参考技术B unicode用4个字节,数字0-0x10ffff来映射字符,有1114112个码位。码位就是可以分配给字符的数字。全世界的字符加起来也用不了所有的码位。
编码解码
一、
文件:字节流,字符流。
字节流:直接将在JVM中处理的unicode的byte[]存入到文件,有数值和字符数据之分(即数值几个字节,字符是几个字节等);
字符流:会将unicode的byte[](包括数值和字符),转换成默认编码(utf-8)的byte[],然后存入到文件。
字符--》字节byte[]--》字符
二、java.class类的编码为:unicode;
Java的class文件采用utf8的编码方式,JVM运行时采用utf16。Java的字符串是unicode编码。
windows 默认的编码为:中文:gb2312; 英文:iso8859;
"中文",unicode存储为"4e2d 6587",如果charset为"gbk",则被编码为"d6d0 cec4",然后返回字节"d6 d0 ce c4".如果charset为"utf8"则最后是"e4 b8 ad e6 96 87".如果是"iso8859-1",则由于无法编码,最后返回 "3f 3f"(两个问号)
1,文件,JVM,文件都是以字节码(byte[])进行处理的,我们看到字符是byte[]通过对应的编码方式映射的。
2,不同编码对byte[]的处理方式不同,对应的映射也不相同。体会由utf8的byte[]编码到unicode的byte[],再由unicode的byte[]解码到utf8的byte[]
3,两层管理,一层:不同编码的byte[],不同编码的byte[]可以通过unicode的byte[]进行转换;二层:每种编码的byte[]怎么对应我们看到的字符
Java采用的编码:unicode,JVM平台默认字符集和外部资源的编码:
文件:utf8的byte[]
JVM:utf8的byte[]转化为unicode的byte[]
文件:需要将unicode的byte[]以哪种编码的byte[]进行存储到文件中
当没有明确指定需要使用的字符编码方案时,Java程序通过“java.nio.charset.Charset.defaultCharset().name()”语句来获取默认的字符编码方案,该语句返回的值跟运行Java程序的操作系统的设置有关,在有些操作系统上,该语句返回值可能是UTF8;在有些操作系统上,该语句返回值可能是GBK;在有些操作系统上,该语句返回值可能是除了UTF8和GBK以外的其他字符编码方案。这样子,程序的可移植性大大降低。
两层结构:由字节流,到编码的字节流,编码映射字符
JVM里面的任何字符串资源都是Unicode,就是说,任何String类型的数据都是Unicode编码。没有例外。既然只有一种编码,那么,我们可以这么说,JVM里面的String是不带编码的。String相当于char[]。
JVM里面的 byte[] 数据是带编码的。比如,Big5,GBK,GB2312,UTF-8之类的。
一个GBK编码的byte[] 转换成 String,其实就是从GBK编码向Unicode编码转换。
一个String转换成一个Big5编码的byte[],其实就是从Unicode编码向Big5编码转换。
所以,Unicode是所有编码转换的中间介质。所有的编码都有一个转换器可以转换到Unicode,而Unicode也可以转换到其他所有的编码。这样构成了一个总线结构。
byte是字节,字符串在网络传输或存储前需要转换为byte数组。在从网络接收或从存储设备读取后需要将byte数组转换成String。String是字符串,可以看成是由char组成的数组。String和char为内存形式,byte是网络传输或存储的序列化形式。
String序列化成byte数组或byte反序列化为String时需要选择正确的编码方式。如果编码方式不正确,就会得到一些0x3F的值。常用的字符编码方式有ISO8859_1、GB2312、GBK、UTF-8/UTF-16/UTF-32。
所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。在读取文件(特别是文本文件)时,也是一个字节一个字节地读取以形成字节序列字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串;
字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。
字节流是最基本的,所有的InputStrem和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的,但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的encode来处理,也就是要进行字符集的转化这两个之间通过InputStreamReader,OutputStreamWriter来关联,实际上是通过byte[]和String来关联 在实际开发中出现的汉字问题实际上都是在字符流和字节流之间转化不统一而造成的
以上是关于unicode字符集是几个字节表示一个字符?为啥需要utf-8?的主要内容,如果未能解决你的问题,请参考以下文章