首页IT科技字符串的编码标准(字符串编码(charset,encoding/decoding)问题原理)

字符串的编码标准(字符串编码(charset,encoding/decoding)问题原理)

时间2025-06-16 11:36:39分类IT科技浏览6067
导读:字符串编码(charset, encoding/decoding 问题原理...

字符串编码(charset, encoding/decoding)问题原理

编码问题很重要                ,关于编码问题的文章也很多               。我本来没有兴趣重复这个主题                        。

一个朋友问我有没有比较好的编码介绍文章        。我记得以前看过几篇很不错的                       ,但是当时搜索到的时候        ,就比较费劲            ,一时想不起来           。于是                       ,我就说           ,我攒一篇好了                       。

---------------------------------------

编码无处不在            。Database, file, editor, IDE, compiler, browser        。

代码(比如java, jsp, asp, php, python, ruby etc)里面的字符串比较麻烦        ,涉及到editor, compiler, interpreter等等                       。

所以                        ,我的做法是               ,从来不在代码里面直接写字符串资源    ,尤其是双字节编码的字符串资源                。

都是把字符串资源分离到一个单独的资源文件里面    。这样                        ,只需要照管这个文件的编码就够了                       。

需要注意的一点是                   ,文件里面                、数据库里面                       、网络传输需要的数据,都是byte[]                    。

以下的讨论                    ,不涉及代码里面的字符串编码问题。只讨论系统运行起来之后                       ,各部分之间的编码问题                   。

先说Java                        。

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也可以转换到其他所有的编码                。这样构成了一个总线结构    。

比如,如果总共有10种编码                    ,那么只需要 10 + 10 = 20个转换器就够了                       。如果要是两两直接转换                       ,那么    ,需要的转换器数量是一个组合数字                ,需要90个转换器                    。

一个系统的不同部分                       ,都有自己的编码。比如        ,数据库            ,文件                       ,JVM           ,浏览器这4个部分                   。

在这些部分之间数据交换的地方        ,就会出现编码问题                        。比如                        ,数据库和JVM之间               ,文件和JVM之间    ,浏览器和JVM之间    。这些问题的原理都是相通的               。

编码问题最容易处理的地方是文件和JVM之间                        。文件IO API带有encoding 参数                        ,请自行查阅        。

最不容易出现编码问题的地方是数据库和JVM之间           。这应该是数据库JDBC连接的基本功能                       。本文不专门进行讨论            。

最容易出问题的地方是浏览器和服务器JVM之间(其实                   ,代码里面的字符串更容易出问题,不过                    ,我已经事先声明                       ,本文不讨论代码中的字符串编码)        。下面主要讨论这块浏览器和服务器JVM之间的编码问题                       。

我们把浏览器编码叫做 Browser_Charset    ,把JVM编码叫做JVM_Charset(通常等于服务器系统编码)                。

当浏览器的数据过来的时候                ,是一个带有Browser_Charset的byte[]    。

如果用户处理程序需要一个String类型的数据                       ,那么JVM会好心好意地把这个byte[]转换成String                       。使用的转换器是 JVM_Charset -> Unicode                    。

注意        ,如果这个时候            ,Browser_Charset 和 JVM_Charset并不相等。那么                       ,这个自动转换是错误的                   。

为了弥补这个错误                        。我们需要做两步工作    。

(1) Unicode -> JVM_Charset           ,把这个String 转换回到原来的 byte[]               。

(2) Browser_Charset -> Unicode        ,把这个还原的byte[]转换成 String                        。

这个效果                        ,和直接从HTTP Request取得byte[]               ,然后执行 (2) Browser_Charset -> Unicode 的效果是一样的        。

如果在Request里面设置了CharacterEncoding    ,那么POST Data参数就不需要自己手工转换了                        ,web server的自动转换就是正确的           。URL的参数编码还涉及到URL编码                   ,需要考虑的问题多一些,没有这么简单                       。

JVM把数据发到浏览器的时候            。也需要考虑编码问题        。可以在Response里面设置                       。另外                    ,HTML Meta Header里面也可以设置编码                       ,提醒Browser选择正确编码                。

有些语言的VM或者解释器的字符串编码可能不同    。比如    ,Ruby                       。不过                ,编码转换原理都是一样的                    。

That is all.

声明:本站所有文章                       ,如无特殊说明或标注        ,均为本站原创发布。任何个人或组织            ,在未征得本站同意时                       ,禁止复制        、盗用            、采集                       、发布本站内容到任何网站           、书籍等各类媒体平台                   。如若本站内容侵犯了原著者的合法权益           ,可联系我们进行处理                        。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
linux解压缩命令 tar.gz(在Linux系统中使用fuser命令来列出进程编号) 电脑非法关机后不能启动怎么解决视频教程图片(电脑非法关机后不能启动怎么解决?)