设为首页收藏本站

ZMX - IT技术交流论坛 - 无限Perfect,追求梦想 - itzmx.com

 找回密码
 注册论坛

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

用百度帐号登录

只需两步,快速登录

搜索
查看: 1647|回复: 0

Java Web 中的中文是怎样进行编码的?

[复制链接]

签到天数: 18 天

[LV.4]偶尔看看III

发表于 2017/3/8 11:22 | 显示全部楼层 |阅读模式 |Google Chrome 53.0.2785.104|Windows XP
天涯海角搜一下: 百度 谷歌 360 搜狗 有道 雅虎 必应 即刻
  1、几种常见的编码格式1.1 为什么要编码
在计算机中存储信息的最小单元是 1 个字节,即 8 个 bit, 所以能表示的字符范围是 0 ~ 255 个。
要表示的符号太多,无法用 1 个字节来完全表示。
1.2 如何翻译
  计算机中提供多种翻译方式,常见的有 ASCII、ISO-8859-1、GB2312、GBK、UTF-8、UTF-16等。这些都规定了转化的规则,按照这个规则就可以让计算机正确的表示我们的字符。下面介绍这几种编码格式:
ASCII 码
  总共有 128 个,用 1 个字节的低 7 位表示, 0 ~ 31 是控制字符如换行、回车、删除等,32 ~ 126 是打印字符,可以通过键盘输入并且能够显示出来。
ISO-8859-1
  128 个字符显然是不够用的,所以 ISO 组织在 ASCII 的基础上扩展,他们是 ISO-8859-1 至 ISO-8859-15,前者涵盖大多数字符,应用最广。ISO-8859-1 仍是单字节编码,它总归能表示 256 个字符。
GB2312
  它是双字节编码,总的编码范围是 A1 ~ F7,其中 A1 ~ A9 是符号区,总共包含 682 个符号;B0 ~ F7 是汉字区,包含 6763 个汉字。
GBk
  GBK 为《汉字内码扩展规范》,为 GB2312 的扩展,它的编码范围是 8140 ~ FEFE(去掉XX7F),总共有 23940 个码位,能表示 21003 个汉字,和 GB2312的编码兼容,不会有乱码。
UTF-16
  它具体定义了 Unicode 字符在计算机中的存取方法。UTF-16 用两个字节来表示 Unicode 的转化格式,它采用定长的表示方法,即不论什么字符用两个字节表示。两个字节是 16 个 bit,所以叫 UTF-16。它表示字符非常方便,没两个字节表示一个字符,这就大大简化了字符串操作。
UTF-8
  虽说 UTF-16 统一采用两个字节表示一个字符很简单方便,但是很大一部分字符用一个字节就可以表示,如果用两个字节表示,存储空间放大了一倍,在网络带宽有限的情况下会增加网络传输的流量。UTF-8 采用了一种变长技术,每个编码区域有不同的字码长度不同类型的字符可以由 1 ~ 6 个字节组成。
  UTF-8 有以下编码规则:
如果是 1 个字节,最高位(第 8 位)为 0,则表示这是一个 ASCII 字符(00 ~ 7F)
如果是 1 个字节,以 11 开头,则连续的 1 的个数暗示这个字符的字节数
如果是 1 个字节,以 10 开头,表示它不是首字节,则需要向前查找才能得到当前字符的首字节
2、在 Java 中需要编码的场景2.1 在 I/O 操作中存在的编码
  Reader 类是在 Java 的 I/O 中读取符的父类,而 InputStream 类是读字节的父类, InputStreamReader 类就是关联字节到字符的桥梁,它负责在 I/O 过程中处理读取字节到字符的转换,而对具体字节到字符的解码实现,它又委托 StreamDecoder 去做,在 StreamDecoder 解码过程中必须由用户指定 Charset 编码格式。值得注意的是,如果你没有指定 Charset,则将使用本地环境中默认的字符集,如在中文环境中将使用 GBK 编码。
  在我们的应用程序中涉及 I/O 操作时,只要注意指定统一的编解码 Charset 字符集,一般不会出现乱码问题。
  2.2 在内存操作中的编码
  在内存中进行从字符到字节的数据类型转换。
  1、String 类提供字符串转换到字节的方法,也支持将字节转换成字符串的构造函数。
  String s = "字符串";byte[] b = s.getBytes("UTF-8"); String n = new String(b, "UTF-8");
  2、Charset 提供 encode 与 decode,分别对应 char[] 到 byte[] 的编码 和 byte[] 到 char[] 的解码。
  Charset charset = Charset.forName("UTF-8"); ByteBuffer byteBuffer = charset.encode(string); CharBuffer charBuffer = charset.decode(byteBuffer);
  ...
  3、在 Java 中如何编解码
  首先根据指定的 charsetName 通过 Charset.forName(charsetName) 设置 Charset 类,然后根据 Charset 创建 CharsetEncoder 对象,再调用 CharsetEncoder.encode 对字符串进行编码,不同的编码类型都会对应到一个类中,实际的编码过程是在这些类中完成的。
  根据 charsetName 找到 Charset 类,然后根据这个字符集编码生成 CharsetEncoder,这个类是所有字符编码的父类,针对不同的字符编码集在其子类中定义了如何实现编码,有了 CharsetEncoder 对象后就可以调用 encode 方法去实现编码了。这个是 String.getBytes 编码方法,其它的如 StreamEncoder 中也是类似的方式。
  经常会出现中文变成“?”很可能就是错误的使用了 ISO-8859-1 这个编码导致的。中文字符经过 ISO-8859-1 编码会丢失信息,通常我们称之为“黑洞”,它会把不认识的字符吸收掉。由于现在大部分基础的 Java 框架或系统默认的字符集编码都是 ISO-8859-1,所以很容易出现乱码问题,后面将会分析不同的乱码形式是怎么出现的。
     Java开发者的薪资不断攀升,IT行业对人才的需求量大,薪资高、前景好,西安华育计算机培训中心紧跟IT市场需求导向,积极为广大学员提供符合市场需要的软件开发技术,一对一的职业规划及就业指导,边工作边学习,实现“T型人才”+项目经验+职业素养。深得学员一致好评。

欢迎光临IT技术交流论坛:http://bbs.itzmx.com/
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册论坛 新浪微博账号登陆用百度帐号登录

本版积分规则

手机版|Archiver|Mail me|网站地图|IT技术交流论坛 ( 闽ICP备13013206号-7 )

GMT+8, 2024/11/19 19:40 , Processed in 0.230043 second(s), 20 queries , MemCache On.

Powered by itzmx! X3.4

© 2011- sakura

快速回复 返回顶部 返回列表