Java编码与解码 - Charset

        在计算机中所有的文件、媒体、信息在底层都是以二进制方式进行存储的。

        要想将计算机底层存储的二进制信息转换成可以直接使用的文件、媒体和信息,就要进行转换,在这个过程中涉及两个概念:编码(Encode)和解码(Decode),通常而言,把明文的字符序列转换成计算机理解的二进制序列(普通人看不懂)称为编码,把二进制序列转换成普通人能看懂的明文字符串称为解码。

        Java默认使用Unicode字符集,但很多操作系统并不使用Unicode字符集,那么当从系统中读取数据到Java程序中时,就可能出现乱码等问题。

        JDK 1.4提供了Charset来处理字节序列和字符序列(字符串)之间的转换关系,该类包含了用于创建解码器和编码器的方法,还提供了获取Charset所支持字符集的方法,Charset类是不可变的。

        //获取Java支持的全部字符集
        SortedMap<String, Charset> charsets = Charset.availableCharsets();
        charsets.forEach((k, v) -> {
            System.out.println(k + ":" + v);
        });
        //获取本地系统的文件编码格式
        System.out.println(System.getProperties().getProperty("file.encoding"));

常用的字符集:

➢ GBK:简体中文字符集。
➢ BIG5:繁体中文字符集。
➢ ISO-8859-1:ISO拉丁字母表No.1,也叫做ISO-LATIN-1。
➢ UTF-8:8位UCS转换格式。
➢ UTF-16BE:16位UCS转换格式,Big-endian(最低地址存放高位字节)字节顺序。
➢ UTF-16LE:16位UCS转换格式,Little-endian(最高地址存放低位字节)字节顺序。
➢ UTF-16:16位UCS转换格式,字节顺序由可选的字节顺序标记来标识。

        调用Charset的forName()方法来创建对应的Charset对象,forName()方法的参数就是相应字符集的别名。

public static Charset forName(String charsetName):返回指定字符集的字符集对象。

参数:
    charsetName – 请求的字符集的名称; 可以是规范名称或别名
返回值:
    命名字符集的字符集对象

        获得了Charset对象之后,就可以通过该对象的newDecoder()newEncoder()这两个方法分别返回CharsetDecoder和CharsetEncoder对象,代表该Charset的解码器和编码器

举例:

        调用CharsetDecoder的decode()方法就可以将ByteBuffer(字节序列)转换成CharBuffer(字符序列)。

        调用CharsetEncoder的encode()方法就可以将CharBuffer或String(字符序列)转换成ByteBuffer(字节序列)。

        //创建简体中文对应的Charset
        Charset cn = Charset.forName("GBK");
        //获取cn对象对应的编码器和解码器
        CharsetEncoder cnEncoder = cn.newEncoder();
        CharsetDecoder cnDecoder = cn.newDecoder();
        //创建一个CharBuffer对象
        CharBuffer cbuff = CharBuffer.allocate(8);
        cbuff.put('独');
        cbuff.put('钓');
        cbuff.put('寒');
        cbuff.flip();
        //将CharBuffer中的字符序列转换成字节序列
        ByteBuffer bbuff = null;
        try {
            bbuff = cnEncoder.encode(cbuff);
            //循环访问ByteBuffer中的每个字节
            for (int i = 0; i < bbuff.capacity(); i++) {
                System.out.print(bbuff.get(i) + " ");
            }
            //将ByteBuffer的数据解码成字符序列
            System.out.println("\n" + cnDecoder.decode(bbuff));
        } catch (CharacterCodingException e) {
            e.printStackTrace();
        }

        将CharBuffer转换成ByteBuffer,将ByteBuffer转换成CharBuffer的功能。实际上,Charset类也提供了如下三个方法。

➢ CharBuffer decode(ByteBuffer bb):将ByteBuffer中的字节序列转换成字符序列的便捷方法。
➢ ByteBuffer encode(CharBuffer cb):将CharBuffer中的字符序列转换成字节序列的便捷方法。
➢ ByteBuffer encode(String str):将String中的字符序列转换成字节序列的便捷方法。

也就是说,获取了Charset对象后,如果仅仅需要进行简单的编码、解码操作,其实无须创建CharsetEncoder和CharsetDecoder对象,直接调用Charset的encode()和decode()方法进行编码、解码即可。提示:
在String类里也提供了一个getBytes(String charset)方法,该方法返回byte[],该方法也是使用指定的字符集将字符串转换成字节序列。

注意:

        Java 7新增了一个StandardCharsets类,该类里包含了ISO_8859_1、UTF_8、UTF_16等类变量,这些类变量代表了最常用的字符集对应的Charset对象。

Guess you like

Origin blog.csdn.net/qq_40100414/article/details/120489974