常见编码
ASCII码,128个,一个字节的低7位表示
ISO-8859-1,256个,单字节
GB2312,中文编码字符集,双字节编码,A1~F7,682个符号,6763个汉字
GBK,汉字内码扩展规范,兼容GB2312,21003个汉字,双字节
UTF-16,定长,用两个字节表示Unicode的转化格式,、
UTF-8,变长,不同类型字符可以由1~6个字节组成,汉字3个字节。
java字符编码转换
一般涉及编码的地方都存在字符到字节或字节到字符的转换上。
I/O操作中的编码
InputStreamReader和OutputStreamWriter
InputStreamReader完成byte流解析为char流,按照编码解析。
OutputStreamWriter完成char流到byte流,按照编码处理。
InputStreamReader isr = new InputStreamReader(new FileInputStream("test1.txt"),"utf-8");//使用文件编码读
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("test2.txt"),"utf-8");//写入文件的编码,可以为其他编码,如gbk
内存操作中的编码
string.getBytes("charsetName")
这是java字符串处理的一个标准函数,其作用是将字符串所表示的字符按照charsetName编码,并以字节方式表示。
newString(byte[],"charsetName")
将字节数组按照charsetName编码进行组合识别,最后转换为unicode存储。
一个简单测试例子:
public class Main {
public static void main(String[] args) {
try {
String test = "一二三",str;
System.out.println(System.getProperty("file.encoding"));//UTF-8
//传输过程中用什么编码,接收时就用什么解码
//测试使用UTF8(三字节)和GBK(二字节)
System.out.println(test.getBytes("UTF8").length);
System.out.println(test.getBytes("GBK").length);
//解码默认,编码默认
str=new String(test.getBytes());
System.out.println(str+str.length());//正常
//解码默认,编码GBK
str=new String(test.getBytes(),"GBK");
System.out.println(str+str.length());//乱码
//解码GBK,编码默认
str=new String(test.getBytes("GBK"));
System.out.println(str+str.length());//乱码
//解码GBK,编码GBK
//虽然test本来默认是三字节编码的,但getBytes("GBK")
//把整个字节数组按双字节形式转换了一次。用GBK来解释这个新字节数组就对了
str=new String(test.getBytes("GBK"),"GBK");
System.out.println(str+str.length());//正常
//回不去?部分字符能转换
str=new String(test.getBytes(),"GBK");
str=new String(str.getBytes("GBK"),"UTF8");
System.out.println(str);
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Charset类
Charset提供encode与decode分别对应char[]到byte[]和byte[]到char[]。
String str = "你好";
Charset charset = Charset.forName("UTF8");
charset.encode(str);
ByteBuffer byteBuffer = charset.encode(str);
CharBuffer charBuffer = charset.decode(byteBuffer);
System.out.println(charBuffer.toString());
JavaWeb中的编码
浏览器编码URL是将非ASCII字符按照某种编码格式编码成16进制数字后,将每个16进制表示的字节前加上“%”。
对URL的URI部分进行解码的字符集是在connector的<Connector URIEncoding=”UTF-8”/>中定义的,没有定义则使用默认编码ISO-8859-1。
而对于QueryString的解析过程,GET和POST都作为parameters保持,对它们的解码是在request.getParameter方法第一次被调用时进行的。
request.setCharacterEncoding()
该函数用来设置http请求或者相应的编码。只对POST方法有效,对GET方法无效。setCharacterEncoding()之前,不能执行任何getParameter()。
对于GET方法,要将connector的<Connector URIEncoding=”UTF-8” useBodyEncodingForURI=”true”/>。
URLEncode.encode()
对的URL编码函数
String mytext = java.net.URLEncoder.encode("中国", "utf-8");
String mytext2 = java.net.URLDecoder.decode(mytext, "utf-8");
//分别为%E4%B8%AD%E5%9B%BD和中国
String zhongguo = new String(request.getParameter("zhongguo").getBytes("iso8859_1"));
zhongguo = java.net.URLDecoder.decode(zhongguo, "utf-8");