Unicode编码和区域编码有什么区别? unicode编码 unicode在线转码( 四 )



Unicode编码和区域编码有什么区别? unicode编码 unicode在线转码

文章插图
图 8. UTF-32 编码
BOM(Byte Order Mark)字节序标记
BOM即Byte Order Mark字节序标记 。BOM是为UTF-16和UTF-32准备的,用来标记字节序(byte order) 。拿UTF-16来举例,其是以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序 。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59 。如果我们收到UTF-16字节流&34;594E&34;,那么这是“奎”还是“乙”?
UTF-8是以单字节为编码单元,没有字节序的问题 。
UTF-16、UTF-32是分别以2个字节和4个字节为编码单位,即1次读取2个字节或4个字节,这样一来,在存储和网络传输时就要考虑1个编码单位内2个字节或4个字节之间顺序的问题 。因此这两种编码方式都存在字节序标记(BOM)问题 。
Big-Endian ( BE )即大端序 : 就是高位字节(即大端字节)存放在内存的低地址,低位字节(即小端字节)存放在内存的高地址 。UTF-16(BE)以 FEFF 作为开头字节,UTF-32(BE)以 00 00 FE FF 作为开头字节;Little-Endian (LE) 即小端序 : 低位字节(即小端字节)存放在内存的低地址,而高位字节(即大端字节)存放在内存的高地址 。UTF-16(LE)以 FFFE 作为开头字节,UTF-32(LE)以 FF FE 00 00 作为开头字节 。UTF-8 不需要 BOM 来表明字节顺序: 可以用 BOM(EF BB BF 称为零宽无间断间隔)来表明编码方式,如果接收者收到以 EF BB BF 开头的字节流,就知道这是 UTF-8 编码 。备注:表 1 中标为 BOM 的地方表示根据文本头部的字节序确定,如果没有字节序,默认为 BE 即大端序编码 。
Unicode编码和区域编码有什么区别? unicode编码 unicode在线转码

文章插图
表 1. Unicode 编码方式中的 BOM
表 2 是几种 Unicode 编码方式示例对比:

Unicode编码和区域编码有什么区别? unicode编码 unicode在线转码

文章插图
表 2. Unicode 编码示例
Unicode 支持在 Java Web 程序中应用实践Unicode 是互联网的基石,为了保证我们的 Web 应用程序很好的支持 Unicode 标准 。从代码角度需要考虑 Unicode 支持的地方有(不限于这些,下面是基于笔者项目实践):
Java 默认字符集设定 :通常情况下如 Windows 系统,我们会通过设置环境变量 JAVA_TOOL_OPTIONS 将默认编码更改为 UTF-8,下面是 Java 程序默认字符集的优先级顺序:
程序执行时使用 Properties 指定的字符集,如 System.getProperties().put(&34;file.encoding&34;,&34;UTF-8);参数-Dfile.encoding 指定的字符集,如 Windows 可以通过设置环境变量 JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8操作系统默认的字符集;JDK 中 JVM 默认的字符集 。JSP: 通过 JSP 页面命令设置 JSP 页面的编码方式(pageEncoding)以及提交表单时所使用的编码方式(charset 属性);
HTML:
设置 Content-Type 属性
Servlet: 设置 response.setContentType(&34;text/html;charset=UTF-8&34;),即服务器端编码方式;
POST 请求:
通过 request.setCharacterEncoding (“UTF-8”)设置解码方式、response.setCharacterEncoding(“UTF-8”)设置服务器端响应数据的编码方式,如清单 3 所示;
清单 1. POST 请求字符编码设置
protected void service(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {// TODO Auto-generated method stubrequest.setCharacterEncoding(&34;UTF-8&34;);response.setCharacterEncoding(&34;UTF-8&34;);}Get 请求: Get 请求方式中请求参数会被附加到地址栏的 URL 之后,URL 组成:域名:端口/contextPath/servletPath/pathInfo?queryString,不同的服务器对 URL 中 pathInfo 和 queryString 解码方式设定不一样,比如 Tomcat 服务器一般在 server.xml 中设定的,Tomcat8 之前的版本默认使用的是 ISO-8859-1,但是 Tomcat 8 默认使用的是 UTF-8,如清单 4 所示;另外对于双字节字符如中日韩等作为 URL 的参数时,最好先 URI 编码后在放到 URL 中 URLEncoder.encode(String.valueOf(c),”UTF-8″);
清单 2. Tomcat server.xml 设置
Tomcat server.xmlXML文档: 设置 transformer.setOutputProperty(OutputKeys.ENCODING, &34;UTF-8&34;);
调用 API 时指定字符集: 调用字符串操作相关或者其他 I/O 操作 API 时,最好指定字符集,如 String.getBytes(“UTF-8”),而不是 String.getBytes();根据情况必要的时候需要写入 BOM 头,例如 Microsoft Office 在读取 csv 文件的时候,它将首先读取 BOM,然后使用 BOM 中的编码打开文件,这种情况下我们在创建或者导出到 CSV 文件的时候,我们需要在代码里面写入 BOM 头 。图 9所示的例子是创建一个 csv 文件的时候没有写入 BOM,用 Office 打开看到的都是乱码,但是用其他编辑器比如 notepad++显示是正常 。当加上 BOM 文件头的时候 fos.write(new byte[]{(byte)0xEF,(byte)0xBB, (byte)0xBF}) 用 Office 再次打开就是正确的字符,代码如清单3 所示 。备注一下,UTF-8 虽然不分大端小端序,但是可以加 BOM 头,表示这个文本是 UTF-8 编码 。