Java字符编码问题

常见编码

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");

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值