打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
java 字符编码处理
最近,在某个项目中遭到中文问题,本来在windows下运行正常的过程,安排到linux下就有问题,凡是从版面request的参数中的中文都变成乱码。在window下,所有穿越request到的中文字符串定然穿越这么转码:new String(str.getBytes("ISO8859-1"));能力获得正常的中文,否则也会获得乱码;然而当过程安排到linux下,即便穿越转码也不行。尔后终于搞打听,在windows下new String(str.getBytes("ISO8859-1"))就相当于new String(str.getBytes("ISO8859-1"),”GB2312”),因为new String()的第二个参数万一不写就利用系统默认值,而在linux下默认值不是GB2312可能GBK,因而有问题,改为new String(str.getBytes("ISO8859-1"),”GBK”)尔后就正常了。而new String()的第一个参数是依据application server的编码定夺的,我批准的是tomcat,tomcat用的编码是ISO8859-1。

在此对其间查阅的材料举行容易的整理。

一、大约观念
2.1 JAVA中字符的表白
JAVA中有char、byte、String这几个观念。char 指的是一个UNICODE字符,为16位的整数。byte 是字节,字符串在网络传输或存储前必需转换为byte数组。在从网络接收或从存储装备读取后必需将byte数组转换成String。String是字符串,能够当做是由char构成的数组。String 和 char 为内存形式,byte是网络传输或存储的序列化形式。
示例:

String ying = “英”;
char ying = ying.charAt(0);
String yingHex = Integer.toHexString(ying);
82 F1
byte yingGBBytes = ying.getBytes(“GBK”);
GB编码的字节数值
D3 A2

2.2 编码措施的简介
String序列化成byte数组或反序列化时必需抉择准确的编码措施。万一编码措施不准确,就会获得一些0x3F的值。常用的字符编码措施有ISO8859_1、GB2312、GBK、UTF-8/UTF-16/UTF-32。
ISO8859_1用来编码拉丁文,它由单字节(0-255)构成。
GB2312、GBK用来编码简体中文,它有单字节和双字节混杂构成。最高位为1的字节和下一个字节构成一个汉字,最高位为0的字节是ASCII码。
UTF-8/UTF-16/UTF-32是国际规范UNICODE的编码措施。用得最多的是UTF-8,重要是因为它在对拉丁文编码时节俭空间。

UNICODE值 UTF-8编码
U-00000000 - U-0000007F: 0******x
U-00000080 - U-000007FF: 110***xx 10******
U-00000800 - U-0000FFFF: 1110***x 10****** 10******
U-00010000 - U-001FFFFF: 11110*** 10****** 10****** 10******
U-00200000 - U-03FFFFFF: 111110xx 10****** 10****** 10****** 10******
U-04000000 - U-7FFFFFFF: 1111110x 10****** 10****** 10****** 10****** 10******

二、判别两个观念:charset 和 encoding!

character set,中文等闲译为“字符集”,切实上它定义的是数值与图形之间的联系。数值有时是个体整数(例如 unicode),有时是一对整数(例如 GB2312)。图形即便这个字的笔划写法。举个例子,在 unicode 中,“21313”这个数值就代表一横一竖的中文“十”字,而在 GB2312 中,则是用“202/174”(即便我们常说的区位码 CA/AE)这对整数代表“十”字。
encoding,好像等闲译为“编码措施”,切实上它定义的是数值在存储和传输时的款式。例如 unicode 中的 21313 这个字符,万一用 UTF-8 款式存储,就会在文件中挪借 3 个字节,它们是 E5/8D/81,但万一用 UCS-2 款式存储,就会在文件中挪借 2 个字节,它们是 41/53。3 个字节也好,2 个字节也好,目标都是为了保留“21313”这个值。而 GB2312 中的 CA/AE,保留成文件也即便这两个字节。

我们平时遭到的词中,unicode、latin-1、CJK 等等,该当都是指 charset,而象 UCS-2、UTF-8 等该当都是指 encoding,至于 GB2312,有些混乱,既表示 charset,也表示 encoding(因为它的存储措施很容易,即便两个字节原样存储)。等闲来说,charset-encoding 是一对多的联系(?)。

回到 JAVA,JDK 的国际版是全程扶持 UNICODE 的,一个重要出现即便它对字符的内部存储款式批准 UCS-2,String.charAt() 获得的值永远是 unicode字符凑近的数值。

三、利用getBytes举行转码
String str =”英”;
//获得GB2312编码的字节
byte[] bytesGB2312 = str.getBytes(“GB2312”);

//获得平台缺省编码的字节(solaris为ISO8859_1,windows为GB2312)
byte[] bytesDefault = str.getBytes();

//用指定的编码将字节转换成字符串
String newStrGB = new String(bytesGB2312, “GB2312”);

//用平台缺省的编码将字节转换成字符串(solaris为ISO8859_1,windows为GB2312)
String newStrDefault = new String(bytesDefault);

//用指定的编码从字节流里面读取字符
InputStream in = ***;
InputStreamReader reader = InputStreamReader( in, “GB2312”);
char aChar = reader.read();

四、利用Charset,CharsetEncoder,CharsetDecoder举行转码

在向 Java 语言迁移时, java.nio.charset 包中有三个类帮助举行这种照射: Charset 、 CharsetEncoder 和 CharsetDecoder 。这些类互相配合,这么您就能够先批准一种照射,然后将其转换为另一种照射。在从另一种照射转换为 Java 照射(Unicode)时,您能够利用解码器(decoder)。然后,万一您必需从 Java 照射(Unicode)再转换为另一种照射(或转换回本来那种照射)时,您能够利用编码器(encoder)。您无法用 java.nio.charset 包在两种非 Unicode 款式之间直接转换,但您能够穿越一种其中的 Unicode 款式在两种非 Unicode 款式间举行转换。

在获得一个解码器或编码器之前,您必需获得用于特定照射的 Charset 。例如,US-ASCII 是用于 7 位 ASCII 字符集的照射的名目。您只需象下面这么把该名目递交到 Charset 的 forName() 措施中即可:

Charset charset =

Charset.forName("US-ASCII");

一旦有了 Charset ,只需按如下所示哀求 CharsetDecoder 和 CharsetEncoder :

CharsetDecoder decoder =

charset.newDecoder();

CharsetEncoder encoder =

charset.newEncoder();

有打听码器和编码器后,您就能够在不同的字符集之间举行转换了,如下所示:

ByteBuffer bytes = ...;

CharBuffer chars = decoder.decode(bytes);

bytes = encoder.encode(chars);

当然,万一不确定哪些字符集可用,您必需用下面的语句来盘问:

SortedMap map =

Charset.availableCharsets();

然后您将利用特定的解码器把表面字节转换为内部字符。然后,万一必需把数据发送到 Java 代码外,您将利用编码器把内部字符转换为表面字节。至于哪些特定的字符集可用,您的运行时将确定全副字符集。但每个 Java 编程告终都定然扶持下列编码:

US-ASCII:7 位 ASCII

ISO-8859-1:ISO 拉丁字母

UTF-8:8 位 UCS 转换款式

UTF-16BE:16 位 UCS 转换款式,大尾数法字节次序

UTF-16LE:16 位 UCS 转换款式,小尾数法字节次序

UTF-16:16 位 UCS 转换款式,用符号(marker)分辨的字节次序

然后,不同的平台可能扶持特定于该平台的额外字符集(例如,在 Windows 平台上,您会觉察它扶持 Windows-1252 字符集)。万一您必需扶持其他的字符集,您能够创立自己的字符集。请参看 java.nio.charset.spi 包中的 CharsetProvider API。


即热式电热水器>五、JSP、数据库的编码
4.1 JSP中的编码
(1) 静态声明:
CHARSET有两个作用:
JSP文件的编码措施:在读取JSP文件、生成JAVA类时www.fo-4.info,源JSP文件中汉字的编码
JSP输出流的编码措施:在厉行JSP时,往response流里面写入数据的编码措施
(2) 动态改换:在往response流里面写数据前能够调用response.setContentType(),设定准确的编码种类。
(3) 在TOMCAT中,由Request.getParameter() 获得的参数,编码措施都是ISO8859_1。因而万一在博览器输入框内输入一个汉字“英”,在服务器端就获得一个ISO8859_1编码的(0x00,0xD3,0x00,0xA2)。因而等闲在接收参数时转码:
String wrongStr = response.getParameter(“name”);
String correctStr = new String(wrongStr.getBytes(“ISO8859_1”),”GB2312”);
在最新的SERVLET规范里面,也能够在获得参数之前厉行如下代码:
request.setCharacterEncoding(“GB2312”);

4.2 数据库的编码
(1) 数据库利用UTF-16
万一String中是UNICODE字符,写入读出时无须要转码
(2) 数据库利用ISO8859_1
万一String中是UNICODE字符,写入读出时必需转码
写入:String newStr = new String(oldStr.getByte(“GB2312”), “ISO8859_1”);
读出:String newStr = new String(oldStr.getByte(“ISO8859_1”),”GB2312”);
六、源文件的编码
5.1 资源文件
资源文件的编码措施和编辑平台相干。在WINDOWS平台下编写的资源文件,以GB2312措施编码。在编译时必需转码,以确保在各个平台上的准确性:
native2ascii –encoding GB2312 source.properties
这么从资源文件中读出的即便准确的UNICODE字符串。
5.2 源文件
源文件的编码措施和编辑平台相干。在WINDOWS平台下开发的源文件,以GB2312措施编码。在编译的时候,必需指定源文件的编码措施:
javac –encoding GB2312
JAVA编译后生成的字节文件的编码为UTF-8。


①最新版TOMCAT4.1.18扶持request.setCharacterEncoding(String enc)
②资源文件转码成company.name=/u82f1/u65af/u514b
③万一数据库利用utf-16则无须要这局部转码
④版面上应有
转码ⅰ:
String s = new String
(request.getParameter(“name”).getBytes(“ISO8859_1”),”GB2312”);
转码ⅱ:
String s = new String(name.getBytes(“GB2312”),”ISO8859_1”);
转码ⅲ:
String s = new String(name.getBytes(“ISO8859_1”),” GB2312”);
附录:资源
http://www-900.ibm.com/developerWorks/cn/theme/unicode.shtml
http://om/data/200109/0608094201.htm

他都感受用C语言这么标兵的面向过程的语言,就能够容易割据,

贪婪算法;局部背包问题;迅速排序O(nlgn);贪婪算法O(n);

利用 Parallel NFS 加深文件系

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Java字符串与字符集的基本概念
java 中String编码和byte 解码 总结
java字符串的各种编码转换类ChangeCharset
【Java 基础专题】编码与乱码(04)---输出时的编码与乱码 - Java - 拼吾爱...
字符,字节和编码
java乱码问题分析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服