编码知识

Unicode和UTF-8

unicode是一个多字节的编码方式,它是一种可以容纳全世界所有文字的编码方式。对于单字节的字符来说,他的unicode就是一个ASCII码;对于多字节来说,他的unicode需要查询unicode的编码表来生成。不论是单字节还是多字节,在存储的时候需要一个字节一个字节地存储,就存在以下几个问题需要解决:

1. 先保存高位字节还是先保存低位字节
2. 只用字节数来编码,还是变换成变长字节来编码(即根据字符的频度或者其他特征来选择是单字节、双字节还是多字节编码)
3. 字节的分界点在哪里,为了让程序知道如何分词

作为一种编码方式,Unicode只规定了如何编码,并没有规定如何传输和保存编码。UTF-8是Unicode编码方式的实现方式之一,它是一种变长字节方案。

GBK/gb2312是用来表示汉子的两种编码。其中GBK既可以表示简体字又可以表示繁体字,而gb2312只可以表示简体字。

UTF-8可以用来表示所有语言,但是不定长。

总之,那么多的编码设计,只是为了更好并且更充分地使用计算机的存储空间。

java编码

java有些与编码相关的函数:
1.  getBytes(charset)
作用是将字符串按照charset编码,因为java的字符串一般都是按照unicode编码并存储的。

2.  new String(charset)
作用是将字符串按照charset识别,并转换成unicode存储。这个方法与上个方法是可逆的,因为
    new String( str.getBytes(charset), charset) == str

3.  request.setCharacterEncoding()
作用是讲字符串在http post时设定编码方式。在执行这条语句之前,不可以使用任何getParameter()命令。

如果调用远程服务得到的是乱码,有几个方法解决问题。

1. 确定返回乱码的编码

    /**
     * check which encoding type is
     * @param str
     * @return
     */
    public static String getEncoding(String str)
    {  
        String encode = "GB2312";  
        try {  
            if (str.equals(new String(str.getBytes(encode), encode))) {  
                String s = encode;  
                return s;  
            }  
        } catch (Exception exception) {  
        }  
        encode = "ISO-8859-1";  
        try {  
            if (str.equals(new String(str.getBytes(encode), encode))) {  
                String s1 = encode;  
                return s1;  
            }  
        } catch (Exception exception1) {  
        }  
        encode = "UTF-8";  
        try {  
            if (str.equals(new String(str.getBytes(encode), encode))) {  
                String s2 = encode;  
                return s2;  
            }  
        } catch (Exception exception2) {  
        }  
        encode = "GBK";  
        try {  
            if (str.equals(new String(str.getBytes(encode), encode))) {  
                String s3 = encode;  
                return s3;  
            }  
        } catch (Exception exception3) {  
        }  
        return "";  
    }  

2. 在提交给url的参数提前做好编码,如把gb2312编成utf-8
    URLEncoder.encode("xxx","utf-8")
当然用了这个方法之后,当得到答案时,可能需要用URLDecoder.decode()解码

3. 读取输入流时确定编码格式
    // 定义 BufferedReader输入流来读取URL的响应
    in = new BufferedReader(
            new InputStreamReader(connection.getInputStream()));

    对于文本文件,可以这么读取
    in = new BufferedReader(
            new InputStreamReader(new InputStreamReader(new FileInputStream("D://test.txt"),"utf-8"));
    读文件时最好用InputStream方式,而不是Reader方式,因为后者会根据jdk指明的编码方式自动把文件内容转换成unicode编码。而且有些文件读取需要强调格式,如
    FileUtils.readLines(new File(fileName), charset);
    有些不需要强制,需要多调试才能得到正确的显示。

    对于数据库的数据,可以先用ResultSet.getBytes()方法取得字节数组,再用
    new String(xxx,charset)重构编码。

网页的乱码

不同操作系统都有一套不同的符号系统,特殊字符的定义也不同。所以这就造成了他们对URL的处理是不同的。Java中的URL类不会对url进行自动的编码和解码工作,所以在出现乱码时,需要用URLEncoder和URLDecoder对编码进行转换。

你可能感兴趣的:(编码)