Java字符集乱码

Java字符集乱码

本节内容

  • 编码与解码

  • 字符集

  • 乱码是如何造成的

文件编码

字符集:

Java字符使用16位的双字节存储,在实际文件存储的数据有各种字符集,要正确操作,否则就有乱码发

字符集表说明
字符集说明
US-ASCII 英文的ASCII
ISO-8859-1 Latin-1拉丁字符,包含中文、日文等
UTF-8 变长unicode字符(1-3个字节),国际通用--->人们常用
UTF-16BE 定长unicode--->(计算机常用)字符(2个字节),大端Big-endian表示(高字节低地址)--->二进制存储相当于一个一个小格子(小方格)越往右地址越低,越往左地址越高
UTF-16LE 定长unicode字符(2个字节),小端little-endian表示(低字节低地址)
UTF-16 文件中开头指定大端还是小端表示方式,既BOM(Byte-Order-Mark):FE FF表示大端,FF FE表示小端--->大小端来源是《格列佛游记》

原理讲解

计算机内部使用二进制进行存储---因为计算机用电压控制事件---门或非门

0101--->字节--->以计算机为中心(计算机只认识字节)

我们能看懂的、写的--->字符

字符--->编码(encode)--->字节(我没希望计算机识别的内容)

字节--->解码(decode)--->字符(计算机的内容展示给我们看)

如何进行编码与解码

简单说有一本大字典,将所有文字收集起来进行数字编号--->码表

编码就是对应的查找字符变成编号

解码就是拿对应的编号去找字符

JVM使用unicode字符集它有两大类

1. 定长--->降低时间复杂度,增加空间复杂度
2. 变长--->节约了空间降低空间复杂度,增加事件复杂度
字符串转成字节数组---编码
public class Variants{
   public static void main(String[] args){
       variants of getBytes()method;
       getBytes();//根据不同的字符集可以进行编码,字符串的常用方法
       getBytes(Charset charset);
       getBytes(String charsetName);
  }
}

实例:

package ioStudy;

import sun.nio.cs.ext.GBK;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;

/**
* 编码(Encode):字符串--->字节
* @author Lucifer
*/
public class ContentEncode {
   public static void main(String[] args) throws UnsupportedEncodingException {

       String msg = "性命生命使命"; //一个中文3个字节
       //对msg进行编码--->可以随意地指定字符集
       byte[] data = msg.getBytes(StandardCharsets.UTF_8); //默认使用的是项目的字符集
       System.out.println(data.length);

       //将data编码成其他字符集
       data = msg.getBytes(StandardCharsets.UTF_16LE); //定长,一个中文2个字节
       System.out.println(data.length);
       data = msg.getBytes("GBK"); //转成GBK字符集的话需要抛出异常---被编码成其他的字符集
       System.out.println(data.length);
  }
}

 

字节数组还原成字符串---解码
package ioStudy;

import java.nio.charset.StandardCharsets;

/**
* 解码(decode):字节数组--->字符串
*/
public class ContentDecodeNo2 {

   public static void main(String[] args) {
       String msg = "性命生命使命";
       //编码
       byte[] data = msg.getBytes(StandardCharsets.UTF_8);

       //解码:将接收到的字节码还原成字符串--->还原过程中可能出现乱码的问题--->解码必须指定正确的编码字符集
       /*
       乱码原因分析
       1.字节数不够--->形参定义的长度和实际的byte数组长度不一致
       2.字符集不统一--->byte数组里面的字符集是utf-8,解码使用的是gbk
        */
       msg = new String(data, 0, data.length, StandardCharsets.UTF_8);
       /*
       源码当中定义了形参
       1.直接放入数组变量
       2,数组变量、起始位置、长度、字符集
        */
       System.out.println(msg);
  }
}

小结

  • 什么是编码什么是解码--->字符串转字节是编码,字节数组转字符串是解码

  • 常用的字符集有那些?--->人是utf-8计算机是unicode,JVM使用的也是unicode

  • 编码与解码转换的实操--->实际代码操作

  •  

 

It's a lonely road!!!
原文地址:https://www.cnblogs.com/JunkingBoy/p/14752487.html