字符串应用之字符串编码转换

2019-03-24 10:56|来源: 网络

无论是对程序的本地化还是国际化,都会涉及到字符编码的转换的问题。尤其在web应用中常常需要处理中文字符,这时就需要进行字符串的编码转换,将字符串编码转换为GBK或者GB2312。


一、关键技术点:
   1、当前流行的字符编码格式有:US-ASCII、ISO-8859-1、UTF-8、UTF-16BE、UTF-16LE、UTF-16、GBK、GB2312等,其中GBK、GB2312是专门处理中文编码的。
   2、String的getBytes方法用于按指定编码获取字符串的字节数组,参数指定了解码格式,如果没有指定解码格式,则按系统默认编码格式。
   3、String的“String(bytes[] bs, String charset)”构造方法用于把字节数组按指定的格式组合成一个字符串对象
   
二、实例演示:

  1. package book.String;  

  2. import java.io.UnsupportedEncodingException;  

  3. /**

  4. * 转换字符串的编码

  5. * @author joe

  6. *

  7. */  

  8. public class ChangeCharset {  

  9.      /** 7位ASCII字符,也叫作ISO646-US、Unicode字符集的基本拉丁块*/  

  10.     public static final String US_ASCII = "US-ASCII";  

  11.      /** ISO拉丁字母表 No.1,也叫做ISO-LATIN-1     */  

  12.     public static final String ISO_8859_1 = "ISO-8859-1";  

  13.      /** 8 位 UCS 转换格式     */  

  14.     public static final String UTF_8 = "UTF-8";  

  15.      /** 16 位 UCS 转换格式,Big Endian(最低地址存放高位字节)字节顺序     */  

  16.     public static final String UTF_16BE = "UTF-16BE";  

  17.      /** 16 位 UCS 转换格式,Litter Endian(最高地址存放地位字节)字节顺序     */  

  18.     public static final String UTF_16LE = "UTF-16LE";  

  19.      /** 16 位 UCS 转换格式,字节顺序由可选的字节顺序标记来标识     */  

  20.     public static final String UTF_16 = "UTF-16";  

  21.      /** 中文超大字符集     **/  

  22.     public static final String GBK = "GBK";  

  23.      

  24.     public static final String GB2312 = "GB2312";  

  25.      

  26.      /** 将字符编码转换成US-ASCII码     */  

  27.      public String toASCII(String str) throws UnsupportedEncodingException {  

  28.         return this.changeCharset(str, US_ASCII);  

  29.     }  

  30.      

  31.      /** 将字符编码转换成ISO-8859-1     */  

  32.      public String toISO_8859_1(String str) throws UnsupportedEncodingException {  

  33.         return this.changeCharset(str, ISO_8859_1);  

  34.     }  

  35.      

  36.      /** 将字符编码转换成UTF-8     */  

  37.      public String toUTF_8(String str) throws UnsupportedEncodingException {  

  38.         return this.changeCharset(str, UTF_8);  

  39.     }  

  40.      

  41.      /** 将字符编码转换成UTF-16BE     */  

  42.      public String toUTF_16BE(String str) throws UnsupportedEncodingException{  

  43.         return this.changeCharset(str, UTF_16BE);  

  44.     }  

  45.      

  46.      /** 将字符编码转换成UTF-16LE     */  

  47.      public String toUTF_16LE(String str) throws UnsupportedEncodingException {  

  48.         return this.changeCharset(str, UTF_16LE);  

  49.     }  

  50.      

  51.      /** 将字符编码转换成UTF-16     */  

  52.      public String toUTF_16(String str) throws UnsupportedEncodingException {  

  53.         return this.changeCharset(str, UTF_16);  

  54.     }  

  55.      

  56.      /** 将字符编码转换成GBK     */  

  57.      public String toGBK(String str) throws UnsupportedEncodingException {  

  58.         return this.changeCharset(str, GBK);  

  59.     }  

  60.      

  61.      /** 将字符编码转换成GB2312     */  

  62.      public String toGB2312(String str) throws UnsupportedEncodingException {  

  63.         return this.changeCharset(str,GB2312);  

  64.     }  

  65.      

  66.      /**

  67.      * 字符串编码转换的实现方法

  68.      * @param str    待转换的字符串

  69.      * @param newCharset    目标编码

  70.      */  

  71.      public String changeCharset(String str, String newCharset)

  72.              throws UnsupportedEncodingException {  

  73.          if(str != null) {  

  74.             //用默认字符编码解码字符串。与系统相关,中文windows默认为GB2312  

  75.             byte[] bs = str.getBytes();  

  76.             return new String(bs, newCharset);    //用新的字符编码生成字符串  

  77.         }  

  78.         return null;  

  79.     }  

  80.      

  81.      /**

  82.      * 字符串编码转换的实现方法

  83.      * @param str    待转换的字符串

  84.      * @param oldCharset    源字符集

  85.      * @param newCharset    目标字符集

  86.      */  

  87.      public String changeCharset(String str, String oldCharset,

  88.              String newCharset) throws UnsupportedEncodingException {  

  89.          if(str != null) {  

  90.             //用源字符编码解码字符串  

  91.             byte[] bs = str.getBytes(oldCharset);  

  92.             return new String(bs, newCharset);  

  93.         }  

  94.         return null;  

  95.     }  

  96.      

  97.      public static void main(String[] args)

  98.              throws UnsupportedEncodingException {  

  99.         ChangeCharset test = new ChangeCharset();  

  100.         String str = "This is a 中文的 String!";  

  101.         System.out.println("str:" + str);  

  102.          

  103.         String gbk = test.toGBK(str);  

  104.         System.out.println("转换成GBK码:" + gbk);  

  105.         System.out.println();  

  106.          

  107.         String ascii = test.toASCII(str);  

  108.         System.out.println("转换成US-ASCII:" + ascii);  

  109.         System.out.println();  

  110.          

  111.         String iso88591 = test.toISO_8859_1(str);  

  112.         System.out.println("转换成ISO-8859-1码:" + iso88591);  

  113.         System.out.println();  

  114.          

  115.         gbk = test.changeCharset(iso88591, ISO_8859_1, GBK);  

  116.         System.out.println("再把ISO-8859-1码的字符串转换成GBK码:" + gbk);  

  117.         System.out.println();  

  118.          

  119.         String utf8 = test.toUTF_8(str);  

  120.         System.out.println();  

  121.         System.out.println("转换成UTF-8码:" + utf8);  

  122.         String utf16be = test.toUTF_16BE(str);  

  123.         System.out.println("转换成UTF-16BE码:" + utf16be);  

  124.         gbk = test.changeCharset(utf16be, UTF_16BE, GBK);  

  125.         System.out.println("再把UTF-16BE编码的字符转换成GBK码:" + gbk);  

  126.         System.out.println();  

  127.          

  128.         String utf16le = test.toUTF_16LE(str);  

  129.         System.out.println("转换成UTF-16LE码:" + utf16le);  

  130.         gbk = test.changeCharset(utf16le, UTF_16LE, GBK);  

  131.         System.out.println("再把UTF-16LE编码的字符串转换成GBK码:" + gbk);  

  132.         System.out.println();  

  133.          

  134.         String utf16 = test.toUTF_16(str);  

  135.         System.out.println("转换成UTF-16码:" + utf16);  

  136.         String gb2312 = test.changeCharset(utf16, UTF_16, GB2312);  

  137.         System.out.println("再把UTF-16编码的字符串转换成GB2312码:" + gb2312);  

  138.     }  

  139.  

  140. }  


str:This is a 中文的 String!
转换成GBK码:This is a 中文的 String!

转换成US-ASCII:This is a ?????? String!

转换成ISO-8859-1码:This is a ?????? String!

再把ISO-8859-1码的字符串转换成GBK码:This is a 中文的 String!


转换成UTF-8码:This is a ????? String!
转换成UTF-16BE码:周楳?猠愠????瑲楮朡
再把UTF-16BE编码的字符转换成GBK码:This is a 中文的 String!

转换成UTF-16LE码:桔獩椠?????匠牴湩Ⅷ
再把UTF-16LE编码的字符串转换成GBK码:This is a 中文的 String!

转换成UTF-16码:周楳?猠愠????瑲楮朡
再把UTF-16编码的字符串转换成GB2312码:?This is a 中文的 String!

三、源码分析:
   更改字符串编码的步骤为:
   1、调用String的getByte方法对字符串进行解码,得到字符串的字节数组(字节数组不携带任何有关编码格式的信息,只有字符才有编码格式)
   2、根据字节数组和新的字符编码构造一个新的String对象,得到的就是按照新的字符编码生成的字符串

【说明】
       java中的String类是按照unicode进行编码的,当使用String(byte[] bytes, String encoding)构造字符串时,encoding所指的是bytes中的数据是按照那种方式编码的,而不是最后产生的String是什么编码方式,换句话说,是让系统把bytes中的数据由encoding编码方式转换成unicode编码。如果不指明,bytes的编码方式将由jdk根据操作系统决定。
       当我们从文件中读数据时,最好使用InputStream方式,然后采用String(byte[] bytes, String encoding)指明文件的编码方式。不要使用Reader方式,因为Reader方式会自动根据jdk指明的编码方式把文件内容转换成unicode编码。

       当我们从数据库中读文本数据时,采用ResultSet.getBytes()方法取得字节数组,同样采用带编码方式的字符串构造方法即可。

  1. ResultSet rs;  

  2. bytep[] bytes = rs.getBytes();  

  3. String str = new String(bytes, "gb2312");  



不要采取下面的步骤。
  1. ResultSet rs;  

  2. String str = rs.getString();  

  3. str = new String(str.getBytes("iso8859-1"), "gb2312");  



   这种编码转换方式效率底。之所以这么做的原因是,ResultSet在getString()方法执行时,默认数据库里的数据编码方式为iso8859-1。系统会把数据依照iso8859-1的编码方式转换成unicode。使用str.getBytes("iso8859-1")把数据还原,然后利用new String(bytes, "gb2312")把数据从gb2312转换成unicode,中间多了好多步骤。

   从HttpRequest中读参数时,利用reqeust.setCharacterEncoding()方法设置编码方式,读出的内容就是正确的了。

顺便说句,如果你直接在浏览器中的地址栏输入这个的话,浏览器都会使用ISO-8859-1来编码你的URL,然后才提交到服务器,这也是为啥一般服务器端都需要首先进行编码转换。


本文链接:字符串应用之字符串编码转换,转自网络

相关问答

更多
  • 1、如果手动转的话,用replace()函数将字符替换成对应的字符。 2、js中有一个专门的转16进制的编码函数:encodeURI() 网址URL中特殊字符转义编码 字符 - URL编码值 空格 - %20 " - %22 # - %23 % - %25 & - %26 ( - %28 ) - %29 + - %2B , - %2C / - %2F : - %3A ; - %3B < - %3C = - %3D > - %3E ? - %3F @ - %40 \ - %5C | - %7C URL特殊字符 ...
  • 1. 使用NSString提供的初始化方法, 将C语言的字符串转为OC中的字符串。 Objective-C 中核心处理字符串的类是 NSString 与 NSMutableString ,这两个类最大的区别就是NSString 创建赋值以后该字符串的内容与长度不能在动态的更改,除非重新给这个字符串赋值。而NSMutableString 创建赋值以后可以动态在该字符串上更改内容与长度。 2. 例程(c语言字符串转成oc字符串): char *Cstring = "This is a String!"; //C ...
  • 字符串
  • //请参考: string a = "1,2,3,4,5"; List list = a.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).Cast ().ToList (); //欢迎追问。
  • StringBuilder sb = new StringBuilder(); // 创建URL URL url = new URL("GBK page URL"); // 打开请求链接 URLConnection page = url.openConnection(); // 以GBK格式读取返回流 BufferedReader in = new BufferedReader(new InputStreamReader(page.getInputStream(),"GBK")); // 读取流内容 Str ...
  • 程序代码: #include #include int strlen(char *s) { int i; for(i=0;s[i]!='\0';i++); return i; } void count(char *s,int *uppercase,int *lowercase,int *space,int *other) { int i; int len=strlen(s); for(i=0;s[i]!='\0';i++)/*对字符串数组只能这样进行遍历即元素的这逐个 ...
  • 函数原形 char *itoa(int value, char *string, int radix) 将整形数value转换为其等价的字符串 头文件stdlib.h Parameters(参数说明) value Number to be converted(将要被转换的值) string String result(转换的结果) radix Base of value; must be in the range 2 – 36 (转换的基数,取值范围2-36。例如radix=10表示10进制,rad ...
  • jsp判断字符为url编码: (1) 浏览器把URL(以及post提交的内容)经过编码后发送给服务器。 (2) 这里的Servlet服务器实际上指的是由Servlet服务器提供的servlet实现ServletRequestWrapper,不同应用服务器的 servlet实现不同,这些servlet的实现把这些内容解码转换为unicode,处理完毕后,然后再把结果(即网页)编码返回给浏览器。 (3) 浏览器按照指定的编码显示该网页。 当对字符串进行编码和解码的时候都涉及到字符集,通常使用的字符集为ISO88 ...
  • 这种编码问题真是很tricky的问题。说它tricky是因为这至少涉及到以下4种编码选取的排列组合(有时甚至更多),更有时乃至会发生错进错出,负负得正,中间过程错了但反而到不是乱码的情况。 (1)源代码的编码 (2)编译时告诉java编译器的源代码编码 (3)运行时jvm参数file.encoding (4)输出终端对输出字节流的解码所采用的码组 在这简单情况下(1)和(2)一致,(3)和(4)一致就不会因为编解码映射错误(当然字符向终端字体映射的错误是另一回事,如字体缺失之类)。而(1)(2)和(3)(4 ...
  • 这适用于长达8个字符的字符串。 编码: SELECT CONV(HEX(string), 16, 10); 要解码: SELECT UNHEX(CONV(number, 10, 16)); MySQL支持最长64位的整数,此方法每个字符使用8位。 因此,使用此方法,您可以在整数中存储最多64/8 = 8个字符。 This will work for strings up to 8 characters long. To encode: SELECT CONV(HEX(string), 16, 10); ...