您的位置:首页 > 编程语言 > Java开发

JAVA基础(二)字节 字符 编码

2016-05-05 22:52 288 查看
乱码或者转码,是开发中经常碰到的问题. 理解了编码到底是怎么回事,解决起来就会轻松很多.

继续提出问题并解决;

1. 位,字节,字符,编码,字符集的概念

2.java中的转码方式

3.常见乱码问题

1. 位,字节,字符,编码,字符集的概念

位(bit): 我们都知道计算机只认识01, 一bit就是这里的一个0或者1.(二进制的01)

字节(byte): 8个bit构成一个byte,可以表示英语字母,数字(这里01是十进制的),还可以表示一些符号.是一个很具体的存储空间.(例如 0x01,
0x45)

字符: 一个或多个字节组合起来代表一个字符.

编码: 字节组合成字符时,需要一定的规则,这个规则就是编码方式.(经常看到说1个汉字=2个字节,其实是错误的,根据编码不同,所需字节也不同)

字符集: 字符按编码规则,能表示出来的字符集合,就是字符集.

各个国家和地区在制定编码标准的时候,“字符的集合”和“编码”一般都是同时制定的。因此,平常我们所说的“字符集”,比如:GB2312, GBK, JIS 等,除了有“字符的集合”这层含义外,同时也包含了“编码”的含义。

下表看下编码的发展历史.

系统内码说明系统
阶段一ASCII计算机刚开始只支持英语,其它语言不能够在计算机上存储和显示。英文 DOS
阶段二ANSI编码

(本地化)
为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。比如:汉字 '中' 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。

不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。

不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。
中文 DOS,中文 Windows 95/98,日文 Windows 95/98
阶段三UNICODE

(国际化)
为了使国际间信息交流更加方便,国际组织制定了 UNICODE 字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。Windows NT/2000/XP,Linux,Java
然后再用表格来区分下字符,字节的概念:
概念描述举例
字符人们使用的记号,抽象意义上的一个符号。'1', '中', 'a', '$', '¥', ……
字节计算机中存储数据的单元,一个8位的二进制数,是一个很具体的存储空间。0x01, 0x45, 0xFA, ……
ANSI

字符串
在内存中,如果“字符”是以 ANSI 编码形式存在的,一个字符可能使用一个字节或多个字节来表示,那么我们称这种字符串为 ANSI 字符串或者多字节字符串"中文123"

(占7字节)
UNICODE

字符串
在内存中,如果“字符”是以在 UNICODE 中的序号存在的,那么我们称这种字符串为UNICODE 字符串或者宽字节字符串L"中文123"

(占10字节)
由于不同 ANSI 编码所规定的标准是不相同的,因此,对于一个给定的多字节字符串,我们必须知道它采用的是哪一种编码规则,才能够知道它包含了哪些“字符”。而对于 UNICODE 字符串来说,不管在什么环境下,它所代表的“字符”内容总是不变的。

2.java中的转码方式

在 C++ 和 Java 中,用来代表“字符”和“字节”的数据类型,以及进行编码的方法:
类型或操作C++Java
字符wchar_tchar
字节charbyte
ANSI 字符串char[]byte[]
UNICODE 字符串wchar_t[]String
字节串→字符串mbstowcs(), MultiByteToWideChar()string = new String(bytes, "encoding")
字符串→字节串wcstombs(), WideCharToMultiByte()bytes = string.getBytes("encoding")
以上需要注意几点:

1)Java 中的 char 代表一个“UNICODE 字符(宽字节字符)”,而 C++ 中的 char 代表一个字节。

2)MultiByteToWideChar() 和 WideCharToMultiByte() 是 Windows API 函数。

3.常见乱码问题

其实,理解了编码是怎么回事以后,乱码问题一般都能轻松解决.
例如:get传参,浏览器会对参数进行encode,按照什么编码进行encode呢?这个就要看浏览器自己的设置了.编码方式不同,后台就没法统一decode,所以一般都是开发自己手动指定编码进行urlencode,后台再进行统一decode, 这里还要注意后台服务器的默认编码,tomcat默认的iso8859-1,所以一般传中文参数,都要在server.xml中指定URIEncoding编码方式.

post传参时,ContentType里面会指定编码,后台服务器一般会写个filter,然后调用request.setCharacterEncodingilter来设置编码.(注意get是这样设置是不生效的)

最简单的原则就是所有地方指定相同的编码.不过总会有例外情况. 当出现乱码时,先找到是哪个环节出现乱码,然后对比俩个环节的编码方式,然后进行适当的转码.

参考文章:
http://www.regexlab.com/zh/encoding.htm http://blog.csdn.net/ygj281583295/article/details/4035386
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: