中文字符用java.lang.String转码的小结(Java/Scala)

先给出最保险的转码操作,既无视平台编码,也无视字符编码:

/** 保证接收到的字符串转为 UTF-8 格式
 *    以 UTF-8 格式编码,再以 UTF-8 格式解码
 */
val strUTF8 = new String(strGBK.getBytes("UTF-8"), "UTF-8")

1. 对字符串的编解码使用了如下四个方法( java.lang.String ),还有其它的几个方法差不多,这里不说了:
     | getBytes(charsetName) :
按指定字符编码格式将 字符串 编码 为字节数组;
     | getBytes() :按平台默认字符编码格式将 字符串 编码 为字节数组;
     | String(bytes, offset, length, charsetName):按指定字符编码格式将 字节数组 解码 为字符串,并指定数组起始;
     | String(bytes, charsetName):按指定字符编码格式将 字节数组 解码 为字符串,按字节数组的默认起始;

    /**
     * @param  charsetName
     *         The name of a supported {@linkplain java.nio.charset.Charset
     *         charset}
     *
     * @return  The resultant byte array
     */
    public byte[] getBytes(String charsetName);

    /* @param  bytes
     *         The bytes to be decoded into characters
     *
     * @param  offset
     *         The index of the first byte to decode
     *
     * @param  length
     *         The number of bytes to decode

     * @param  charsetName
     *         The name of a supported {@linkplain java.nio.charset.Charset
     *         charset}
     */
    public String(byte bytes[], int offset, int length, String charsetName);
    /**
     * @return  The resultant byte array
     */
    public byte[] getBytes();

    /**
     * @param  bytes
     *         The bytes to be decoded into characters
     *
     * @param  charsetName
     *         The name of a supported {@linkplain java.nio.charset.Charset
     *         charset}
     */
    public String(byte bytes[], String charsetName);

 

2. 中文字符 在 GBK 与 UTF-8 间的转换:
     | 因为中文字符 以 GBK 编码时占2个字节,以 UTF-8 编码时占3个字节;
     | 所以从 UTF-8 格式转为 GBK 格式时,只是丢失了高位字节
,不会存在问题
    
| 但如果 GBK 格式转为 UTF-8 格式时,不存在 UTF-8 的高位字节,所以会出现乱码;
     | 幸好这一切 java.lang.String 都处理好了。
     | *** 【慎用】 如下第二中方式,指定字节数组长度,除非指定正确;
      —| 1) 小于 UTF-8 格式编码时的字节长度,结果是最后的几个中文字符出现乱码;
      —| 2) 大于 UTF-8 格式编码时的字节长度,结果是数组下标越界异常。

// 1. 使用默认的字节数组长度
val strUTF8 = new String(strGBK.getBytes("UTF-8"), "UTF-8")
// 2. 或者 指定转为UTF-8的字节长度
//    这种方式如果指定的字节数组小于UTF-8编码后的字节数组长度,最后几个中文字符会出现乱码
val strUTF8 = new String(strGBK.getBytes("UTF-8"), 0, strGBK.length()*3, "UTF-8")
// 3. (推荐)使用 UTF-8 编解码格式
val strUTF8 = new String(strGBK.getBytes("UTF-8"), "UTF-8")

3. 完整测试代码(scala/java): 

object a extends App {
  
  testUTF8ToGBK
  testGBKToUTF8
  
  def testUTF8ToGBK = {
    println("-------------------[Test UTF8 To GBK]-------------------------")
    val strBytes = new String("中文").getBytes("UTF-8")
    println("strBytes: " + strBytes.mkString(" "))
    
    val strUTF8 = new String(strBytes, "UTF-8")
    println("strUTF8 Bytes: " + strUTF8.getBytes("UTF-8").mkString(" "))
    
    // 使用默认的字节数组长度
    val strGBK = new String(strUTF8.getBytes("GBK"), "GBK")
//    // 或者 指定转为GBK的字节长度
//    val strGBK = new String(strUTF8.getBytes("GBK"), 0, strUTF8.length()*2, "GBK")
    println("strGBK Bytes: " + strGBK.getBytes("GBK").mkString(" "))
    
    println("strUTF8: " + strUTF8)
    println("strGBK: " + strGBK)
  }
  
  def testGBKToUTF8 = {
    println("-------------------[Test GBK To UTF8]-------------------------")
    val strBytes = new String("中文").getBytes("GBK")
    println("strBytes: " + strBytes.mkString(" "))
    
    val strGBK = new String(strBytes, "GBK")
    println("strGBK Bytes: " + strGBK.getBytes("GBK").mkString(" "))
    
//    // 1. 使用默认的字节数组长度
//    val strUTF8 = new String(strGBK.getBytes("UTF-8"), "UTF-8")
//    // 2. 或者 指定转为UTF-8的字节长度
//    //    这种方式如果指定的字节数组小于UTF-8编码后的字节数组长度,会出现乱码
//    val strUTF8 = new String(strGBK.getBytes("UTF-8"), 0, strGBK.length()*3, "UTF-8")
    // 3. (推荐)使用 UTF-8 编解码格式
    val strUTF8 = new String(strGBK.getBytes("UTF-8"), "UTF-8")
    println("strUTF8 Bytes: " + strUTF8.getBytes("UTF-8").mkString(" "))
    
    println("strGBK: " + strGBK)
    println("strUTF8: " + strUTF8)
  }
  
}
-------------------[Test UTF8 To GBK]-------------------------
strBytes: -28 -72 -83 -26 -106 -121
strUTF8 Bytes: -28 -72 -83 -26 -106 -121
strGBK Bytes: -42 -48 -50 -60
strUTF8: 中文
strGBK: 中文
-------------------[Test GBK To UTF8]-------------------------
strBytes: -42 -48 -50 -60
strGBK Bytes: -42 -48 -50 -60
strUTF8 Bytes: -28 -72 -83 -26 -106 -121
strGBK: 中文
strUTF8: 中文

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值