Java中字符串编码相关操作

主要的几种编码方式:

Java中字符的编码:
同一种 编码格式,字节流的存储方式也可能不一样,例如UTF-8是一种变长字节编码方式

编码格式:
查看当前系统的默认编码方式,一般为GBK
System.getProperty("file.encoding")

枚举所有可用编码方式
Map<String,Charset> map=Charset.availableCharsets();
for(Map.Entry<String,Charset> entry:map){
entry.getKey();
}

与字符串有关方法的解析:
String string="阿";
/*字符串到字节流*/
byte[] bytesDefault=string.getBytes();     //以该编码方式把字符串以系统默认编码的方式解析成字节流。
byte[] bytesUTF8=string.getBytes("UTF-8");     //以指定的UTF-8编码方式把字符串解析成字节流
/*字节流到字符串*/
String newString=new String(bytesDefault,"UTF-8");    //将所给的字符流以UTF-8的方式编码为字符串
/*字符到索引*/
int index=(int)string.charAt(0);    //指定位置字符在系统默认编码方式下的索引
String hexIndex=Integer.toHexString(index);    //数的十六进制表示
/*索引到字符*/
String charStr=String.valueOf((char)index);    //系统默认编码方式中该索引对应的字符
/*字符串到字节流*/
URLEncoder.encode(string, "UTF-8")      //字符串以3字节UTF-8形式存储时的字节流形式
/*字节流到字符串*/
byteStr=" "%E9%B8%BF" ";    //示例
URLDecoder.decode(byteStr, "UTF-8")      //3字节UTF-8字节流转化为字符串

索引到字节流可以用类似URLDecoder的类来解决,也可以自己写代码以其他方式,例如转化为6字节UTF-8字节流。
这时可能还需要写一段字节流到索引的方法,因为 如果要以转化成3字节以外的UTF8字节流方式存储,是可以以UTF8的方式正常解码,却无法用URLDecoder得到索引。

下面是一段字符索引到字符串的代码,可以用数字表示单个索引,也可以固定的utf-8编码格式表示多个索引

private static final Pattern unicodeReg=Pattern.compile("[0-9A-Fa-f]{4}");
//3Bytes
 public static String UTF8ToString(int code) throws UnsupportedEncodingException{
  byte[] strbyte=new byte[4];
  strbyte[0]=(byte) ((code>>12&0x000F)|0x00E0);//1110XXXX
  strbyte[1]=(byte) ((code>>6&0x003F)|0x00B0);//10XXXXXX
  strbyte[2]=(byte) ((code&0x003F)|0x00B0);//10XXXXXX
  return new String(strbyte,"UTF-8");
 }
 //3Bytes
 public static String UTF8ToString(String code) throws UnsupportedEncodingException{
  byte[] strbyte=new byte[4*(code.length()/6)];
  for(int i=0;i<code.length();i++){
   if('\\'==code.charAt(i)&&'u'==code.charAt(i+1)){
    Matcher matcher=unicodeReg.matcher(code.substring(i+2,i+6));
    if(matcher.find()){
     int strcode=Integer.parseInt(code.substring(i+2,i+6),16);
     strbyte[i*4]=(byte) ((strcode>>12&0x000F)|0x00E0);//1110XXXX
     strbyte[i*4+1]=(byte) ((strcode>>6&0x003F)|0x00B0);//10XXXXXX
     strbyte[i*4+2]=(byte) ((strcode&0x003F)|0x00B0);//10XXXXXX
     i+=6;
    }
   }
  }
  String result;
  result=new String(strbyte,"UTF-8");
  return result;
 }

PS:测试的时候不要写错成unicode的转义字符,用\\uXXXX\\uXXXX\\uXXXX的形式测试,下面是Java中所有转义字符
http://blog.csdn.net/caimo/article/details/10960285

在使用百度搜索的时候,其实可以直接实现字符串到3字节UTF8字节流的转换,搜索任意中文字符,地址栏中的word参数值就是字节流(Chrome貌似做了转换,把全部地址 复制出来就可以了,IE可以看到)。
比如搜索“二叉树”,地址内容是

https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&wd=%E4%BA%8C%E5%8F%89%E6%A0%91&rsv_pq=fb32fec60000d348&rsv_t=d701K52XrcHEiBAg14OTk%2F1%2FxAPPGvBMUsdV8IesAtsUAGTJbTE4zvtW5MM&rsv_enter=1&rsv_sug3=5&rsv_sug1=4&rsv_pq=fb32fec60000d348&rsv_t=d701K52XrcHEiBAg14OTk%2F1%2FxAPPGvBMUsdV8IesAtsUAGTJbTE4zvtW5MM&rsv_enter=1&rsv_sug3=5&rsv_sug1=4
这里的 %E4%BA%8C%E5%8F%89%E6%A0%91就是我们要的字节流。
这里一个小插曲,如果UTF-8编码方式被错误解析成GBK(GB2312)编码格式,会出现什么字符呢?
只要把ie=utf-8改成ie=ISO8859就可以看到了,被错误解析的字符会比原来多1/3个。
因为我的系统默认编码就是GBK,所以猜测在客户端有这样的机制,即 当指定查询字节流时,网页会认为查询的是中文字符串,如果没有指定正确的中文字符集,客户端自动指定默认编码格式为GBK,并将其与查询的字节流一并发送到服务器,服务器即以所指定的GBK编码格式解析成中文,进行查询并返回结果。
这里还要PS一下,这里的GBK编码和网络上查询相应字符得到的GBK编码不一样,因为这里的GBK编码是已经按固定格式(例如UTF8的3字符格式)转换好的,具体转换原理还要研究一下。比如说我在Nodepad里输入这么一串字符串
E4BA8CE58F89E6A091,HexToASCII后,在GB2312编码下是浜屽弶鏍?,而实际上E4BA在网上查不到对应的GBK编码(似乎9FB3是最后一个),GBK编码的生成方式暂时还要研究一下~



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值