3.1 容易产生的误解

对编码的误解

误解一

在将“字节串”转化成“UNICODE 字符串”时,比如在读取文本文件时,或者通过网络传输文本时,容易将“字节串”简单地作为单字节字符串,采用每“一个字节”就是“一个字符”的方法进行转化。

而实际上,在非英文的环境中,应该将“字节串”作为 ANSI 字符串,采用适当的编码来得到 UNICODE 字符串,有可能“多个字节”才能得到“一个字符”。

通常,一直在英文环境下做开发的程序员们,容易有这种误解。

误解二

在 DOS,Windows 98 等非 UNICODE 环境下,字符串都是以 ANSI 编码的字节形式存在的。这种以字节形式存在的字符串,必须知道是哪种编码才能被正确地使用。这使我们形成了一个惯性思维:“字符串的编码”。

当 UNICODE 被支持后,Java 中的 String 是以字符的“序号”来存储的,不是以“某种编码的字节”来存储的,因此已经不存在“字符串的编码”这个概念了。只有在“字符串”与“字节串”转化时,或者,将一个“字节串”当成一个 ANSI 字符串时,才有编码的概念。

不少的人都有这个误解。

第一种误解,往往是导致乱码产生的原因。第二种误解,往往导致本来容易纠正的乱码问题变得更复杂。

在这里,我们可以看到,其中所讲的“误解一”,即采用每“一个字节”就是“一个字符”的转化方法,实际上也就等同于采用 iso-8859-1 进行转化。因此,我们常常使用 bytes = string.getBytes("iso-8859-1") 来进行逆向操作,得到原始的“字节串”。然后再使用正确的 ANSI 编码,比如 string = new String(bytes, "GB2312"),来得到正确的“UNICODE 字符串”。

3.2 非 UNICODE 程序在不同语言环境间移植时的乱码

非 UNICODE 程序中的字符串,都是以某种 ANSI 编码形式存在的。如果程序运行时的语言环境与开发时的语言环境不同,将会导致 ANSI 字符串的显示失败。

比如,在日文环境下开发的非 UNICODE 的日文程序界面,拿到中文环境下运行时,界面上将显示乱码。如果这个日文程序界面改为采用 UNICODE 来记录字符串,那么当在中文环境下运行时,界面上将可以显示正常的日文。

由于客观原因,有时候我们必须在中文操作系统下运行非 UNICODE 的日文软件,这时我们可以采用一些工具,比如,南极星,AppLocale 等,暂时的模拟不同的语言环境。

3.3 网页提交字符串

当页面中的表单提交字符串时,首先把字符串按照当前页面的编码,转化成字节串。然后再将每个字节转化成 "%XX" 的格式提交到 Web 服务器。比如,一个编码为 GB2312 的页面,提交 "中" 这个字符串时,提交给服务器的内容为 "%D6%D0"。

在服务器端,Web 服务器把收到的 "%D6%D0" 转化成 [0xD6, 0xD0] 两个字节,然后再根据 GB2312 编码规则得到 "中" 字。

在 Tomcat 服务器中,request.getParameter() 得到乱码时,常常是因为前面提到的“误解一”造成的。默认情况下,当提交 "%D6%D0" 给 Tomcat 服务器时,request.getParameter() 将返回 [0x00D6, 0x00D0] 两个 UNICODE 字符,而不是返回一个 "中" 字符。因此,我们需要使用 bytes = string.getBytes("iso-8859-1") 得到原始的字节串,再用 string = new String(bytes, "GB2312") 重新得到正确的字符串 "中"。

3.4 从数据库读取字符串

通过数据库客户端(比如 ODBC 或 JDBC)从数据库服务器中读取字符串时,客户端需要从服务器获知所使用的 ANSI 编码。当数据库服务器发送字节流给客户端时,客户端负责将字节流按照正确的编码转化成 UNICODE 字符串。

如果从数据库读取字符串时得到乱码,而数据库中存放的数据又是正确的,那么往往还是因为前面提到的“误解一”造成的。解决的办法还是通过 string = new String( string.getBytes("iso-8859-1"), "GB2312") 的方法,重新得到原始的字节串,再重新使用正确的编码转化成字符串。

3.5 电子邮件中的字符串

当一段 Text 或者 HTML 通过电子邮件传送时,发送的内容首先通过一种指定的字符编码转化成“字节串”,然后再把“字节串”通过一种指定的传输编码(Content-Transfer-Encoding)进行转化得到另一串“字节串”。比如,打开一封电子邮件源代码,可以看到类似的内容:

Content-Type: text/plain;

charset="gb2312"

Content-Transfer-Encoding: base64

sbG+qcrQuqO17cf4yee74bGjz9W7+b3wudzA7dbQ0MQNCg0KvPKzxqO6uqO17cnnsaPW0NDEDQoNCg==

最常用的 Content-Transfer-Encoding 有 Base64 和 Quoted-Printable 两种。在对二进制文件或者中文文本进行转化时,Base64 得到的“字节串”比 Quoted-Printable 更短。在对英文文本进行转化时,Quoted-Printable 得到的“字节串”比 Base64 更短。

邮件的标题,用了一种更简短的格式来标注“字符编码”和“传输编码”。比如,标题内容为 "中",则在邮件源代码中表示为:

// 正确的标题格式

Subject: =?GB2312?B?1tA=?=

其中,

第一个“=?”与“?”中间的部分指定了字符编码,在这个例子中指定的是 GB2312。

“?”与“?”中间的“B”代表 Base64。如果是“Q”则代表 Quoted-Printable。

最后“?”与“?=”之间的部分,就是经过 GB2312 转化成字节串,再经过 Base64 转化后的标题内容。

如果“传输编码”改为 Quoted-Printable,同样,如果标题内容为 "中":

// 正确的标题格式

Subject: =?GB2312?Q?=D6=D0?=

如果阅读邮件时出现乱码,一般是因为“字符编码”或“传输编码”指定有误,或者是没有指定。比如,有的发邮件组件在发送邮件时,标题 "中":

// 错误的标题格式

Subject: =?ISO-8859-1?Q?=D6=D0?=

这样的表示,实际上是明确指明了标题为 [0x00D6, 0x00D0],即 "中",而不是 "中"。

4. 几种错误理解的纠正

误解:“ISO-8859-1 是国际编码?”

非也。iso-8859-1 只是单字节字符集中最简单的一种,也就是“字节编号”与“UNICODE 字符编号”一致的那种编码规则。当我们要把一个“字节串”转化成“字符串”,而又不知道它是哪一种 ANSI 编码时,先暂时地把“每一个字节”作为“一个字符”进行转化,不会造成信息丢失。然后再使用 bytes = string.getBytes("iso-8859-1") 的方法可恢复到原始的字节串。

误解:“Java 中,怎样知道某个字符串的内码?”

Java 中,字符串类 java.lang.String 处理的是 UNICODE 字符串,不是 ANSI 字符串。我们只需要把字符串作为“抽象的符号的串”来看待。因此不存在字符串的内码的问题。

文章引用自:

posted on 2007-09-13 22:34 Ke 阅读(1150) 评论(0)  编辑  收藏 所属分类: encoding

java向led屏下发字符串乱码_几种误解,以及乱码产生的原因和解决办法相关推荐

  1. Java日记_17.9.01——点击按钮后,键盘监听失效的原因与解决办法

    最近在自学JAVA,听了前辈的安利在做自己的小画板,然后悲剧就发生了,同时添加按钮和键盘监听之后,就产生了如题的问题,一直觉得是自己监听事件注册的不对,改了一天,然后终于找到了原因,真的巨坑啊我觉得q ...

  2. qt5使用触屏 偶尔没响应_微软surface触摸失灵,触摸屏幕无法响应系统解决办法...

    触摸屏幕无法响应(适用所有Surface系列) 发生该问题的原因可能是:有很多可能原因,从校准到硬件或者固件.故障排查可以找到根本原因. 1.清洁屏幕 将柔软的无绒布蘸上水或眼镜清洗液来清洁屏幕,但不 ...

  3. 罗斯蒙特电磁流量计8723说明书_罗斯蒙特8732E电磁流量计故障原因及解决办法!...

    今天我们来说说罗斯蒙特8732E电磁流量计的一些基本故障和解决办法,我们在排除电磁流量计的故障时,确定问题至关重要.下面提供了无法正常工作的电磁流量计表现出的常见症状.此表提供了潜在的原因以及为每种症 ...

  4. python车牌识别系统抬杆_车牌识别系统不抬杆的原因和解决办法

    目前很多停车场.小区都使用了车牌识别系统来对车辆进行管理,但是在使用的过程中会有一些突发状况,比如车牌识别系统不抬杆.那么车牌识别系统不抬杆怎么办呢?下面南天瑞丰给大家分享车牌识别系统不抬杆的原因和解 ...

  5. 横河川仪压力变送器故障代码_日本横河川仪EJA变送器故障原因及解决办法!

    我们在使用横河EJA变送器时难免出出现一些故障,有的是外部环境引起的,有的是操作不当,有的是产品质量,对于不是很懂的客户,当产品出现故障时不知怎么办,下面我整理了日本横河变送器公司公布的官方变送器故障 ...

  6. mysql.exe不运行_求解mysql进程mysqld.exe无法启动原因及解决办法

    求解mysql进程mysqld.exe无法启动原因及解决方法 120908 20:03:20 [Note] Plugin 'FEDERATED' is disabled. 120908 20:03:2 ...

  7. 网页突然乱码_网站内中文出现乱码的五个原因

    网站内中文出现乱码的五个原因 来源:昆明网络公司 日期:2010-09-26 阅读: 发表评论 网站存在互联网上,联通着全世界的网民,一个网站一上线,这个世界所有连接互联网的人们都能看到,但网站也有& ...

  8. mysql保存中文乱码的原因和解决办法

    当你遇到这个mysql保存中文乱码问题的时候,期待找到mysql保存中文乱码的原因和解决办法这样一篇能解决问题的文章是多么激动人心.   也许30%的程序员会选择自己百度,结果发现网友已经贴了很多类似 ...

  9. 中文字符乱码的原因及解决办法

    中文字符乱码的原因及解决办法 java的内核是Unicode的,也就是说,在程序处理字符时是用Unicode来表示字符的,但是文件和流的保存方式是使用字节流的.在java的基本数据类型中,char是U ...

  10. com/opensymphony/xwork2/spring/SpringObjectFactory.java:220:-1问题出现的原因及解决办法

    转自:https://blog.csdn.net/shinchan_/article/details/37818927 com/opensymphony/xwork2/spring/SpringObj ...

最新文章

  1. 【转】C++面试题(四)——智能指针的原理和实现
  2. 用基本控件简单地仿QQ登录界面
  3. 科大星云诗社动态20220101
  4. another CRM inbound debug - 另一个CRM中间件的调试记录
  5. 自定义UITabBar的背景图片或者颜色
  6. BNU10791:DOTA选人
  7. 数字化转型方法论_老板让我搞数字化转型?成功之后,我整理了这套超全的方法论...
  8. c语言学生综合测评系统_综合测评线上系统帮助文档
  9. 【Java】 Java反射机制总结
  10. 0606-工厂模式、单例模式、DBDA的单例和完整功能
  11. Visual C++中的ODBC编程
  12. 计算机桌面不来回变黑,电脑屏幕变小了左右黑几种解决方法
  13. 自定义---单批次训练函数
  14. 再谈 最速下降法/梯度法/Steepest Descent
  15. SM2算法和RSA算法简介
  16. 英特尔傲腾内存linux,英特尔一面优化傲腾可持续内存性能 一面不忘科普
  17. 多多自走棋服务器不稳定,《多多自走棋》将登陆Epic平台 PC版数据将与移动版互通...
  18. Android心率测试
  19. 一个生成随机密码的WPF小程序
  20. mysql查询平均工资最低的部门_查询出部门名称、部门的员工数、部门的平均工资、部门的最低收入雇员姓名和最高收入雇员的姓名...

热门文章

  1. xmind电脑安卓v2021.20.8免费全平台永久思维导图直装版
  2. 武汉大学计算机学院成绩单,2018年武汉大学各学院总评成绩计算公式汇总
  3. vbscript运行环境linux,VBScript 是什么?
  4. Ecshop系统框架分析之二次开发重点结构介绍
  5. 发邮件向论文作者卑微求代码模板
  6. 动易html在线编辑器,动易CMS静态页调用FCK编辑器的代码
  7. 动易软件向网站服务器上传软件,动易CMS粘贴图片自动上传到服务器(Java版)
  8. 互联网日报 | 微信红包封面向个人开放;每日优鲜获青岛战略投资20亿元;中国银联发布“银联云”...
  9. 谈谈网络协议,常见的网络协议有那些?
  10. 手把手带你SQLite3快速入门