主要的几种编码方式:

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);    //系统默认编码方式中该索引对应的字符 

 

  /*字符串到字节流*/ 

 
 //字符串以3字节UTF-8形式存储时的字节流形式
 

  /*字节流到字符串*/ 

 
"%E9%B8%BF" 
 ";    //示例
 
 //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中所有转义字符

在使用百度搜索的时候,其实可以直接实现字符串到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编码的生成方式暂时还要研究一下~