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

本文介绍字符编码的基础知识,并通过Java代码示例展示了如何在不同字符集(如GBK、GB2312、UTF-8等)间转换字符串。重点讲解了使用String类的getBytes方法及构造函数进行编码转换的技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

无论是对程序的本地化还是国际化,都会涉及到字符编码的转换的问题。尤其在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,然后才提交到服务器,这也是为啥一般服务器端都需要首先进行编码转换。


点击打开链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值