关于java:你了解java中的几种编码方式解决乱码问题可能并不麻烦

4次阅读

共计 2962 个字符,预计需要花费 8 分钟才能阅读完成。

前言

编码的转换通常在 IO 机制中应用,一个好的编码能够为咱们节俭很多空间,在某种程度上进步咱们利用的效率。因为之前就晓得 String 中的转换形式,还有一些工具类,因而明天就好好的整顿一下 java 中 jdk 提供的几种转换形式,心愿对你有帮忙。

一、编码转换原理

1、为什么须要编码

咱们晓得计算机存储信息的最小单位是一个字节 8 位,可能示意 256 个字符。这对于早起的英文来说足够了。即便是加上一些常见符号也足够。于是在 1965 年美国制订了 ASCII 编码,次要用于英语和西欧语言,一开始 128 个,起初加到了 256。

起初随着工夫的倒退,中国、日本等国的计算机也开始蓬勃发展,于是计算机不仅仅要存储英文了,也开始存储中文。然而中文咱们都晓得几万个太多了,一个字节必定放不下。怎么办呢?一个字节示意不下,那就多用几个字节就好了。这样不仅能够示意汉字,还能够防止了与 ASCII 编码的抵触。这几个字节在存储的时候再转化为 bit,完满! 划重点哈,编码解决的就是字节和字符之间的转化问题。

2、编码方式

既然是编码,那些大佬早就思考到了这些问题,并提拱了多种编码方式,常见的有 ASCII、ISO-8859-1、GB2312、GBK、UTF-8、UTF-16 等。它们规定了转化的规定,依照这个规定就能够让计算机正确的示意咱们的字符。

像 GB2312、GBK、UTF-8、UTF-16 等很多种形式都能够示意汉字,他们有什么区别呢?

(1)GB2312

它是双字节编码,总的编码范畴是 A1-F7,其中从 A1-A9 是符号区,总共蕴含 682 个符号,从 B0-F7 是汉字区,蕴含 6763 个汉字。这个是中国 1981 年搞进去的。 这种编码是一个汉字两个字节。

(2)GBK

它的编码范畴是 8140~FEFE(去掉 XX7F)总共有 23940 个码位,它能示意 21003 个汉字。这个是中国在 1995 年搞进去的,次要是用于 GB2312 编码的补充。 这种编码仍然是一个汉字两个字节。

(3)Unicode

下面看到,中国能够做出了一个编码,日本也能够做进去一个编码,工夫久了每个国家都有着本人的一套编码,就不可避免的造成抵触。于是 Unicode 进去了,把所有语言对立起来合成一个规定。 这种编码是定长的字节数。

(4)UTF8

既然 Unicode 是定长的字节数,那么存储一个简单的汉字可能须要三个字节,然而为了保障是 2 的幂数集,就会主动裁减为 4 个字节,别看着一个字节之差,存储的字数多了就会极大的节约空间。是于是而 UTF-8 采纳了一种变长技术,每个编码区域有不同的字码长度。不同类型的字符能够是由 1~6 个字节组成。

以上这些编码方式会为每一个汉字或者是字母建设一个编码库,在编码的时候字母和编码一一对应。

3、为什么会呈现乱码?

这个问题就是因为编码和解码是采纳了不同的或者是不兼容的编码方案。比方一个用 UTF- 8 编码的后的字符。再用 GBK 去解码,因为两个字符集的编码库不一样。同一个汉字在两个编码库的地位也不一样。于是就呈现了乱码。

4、java 如何解决乱码问题?

这个问题其实就是 java 中如何应用编码规定,因为应用好了编码规定。才能够很好地解决乱码问题。

(1)IO 流

编码的目标下面曾经说了,次要是字节和字符之间的转化。既然波及到字节和字符很容易咱们就能想到 java 中的 IO 流。也就是说 java 中编码的转换其实就是 IO 流中的类来实现的。

最外围的就是下面几个类,当然这里只是给出了输出的一部分,还有一些输入的类。

(2)String

String 类中也提供了一些转码的办法。上面咱们会通过实例来阐明。为什么 String 能够实现呢?这是因为 String 底层保留的其实就是一个一个字节,而且 String 还有办法间接转化为字符。所以 String 必定也能实现。

(3)Charset

这个 Charset 是 javaNIO 中的一个类,整个流程就是读取数据,而后转化为 byte,也就是字符。而后从新编码成字符就 OK 了。

上面咱们应用代码来实现一下:

二、代码实现

1、IO 流

首先是 IO 流实现,这种通过输入输出流能够间接的指定编码规定。

`public void convertionFile() throws IOException {
  File file = new File(“./ 愚公要移山.txt”);
  FileInputStream fis = new FileInputStream(file);
  InputStreamReader inReader = new InputStreamReader(fis, “gbk”);
  FileOutputStream fos = new FileOutputStream(file);
  OutputStreamWriter outReader = new OutputStreamWriter(fos, “utf-8”);
        // 这种输出 gbk,输入 utf- 8 必定会呈现谬误
 }`

2、String

应用 string 是最不便的,代码也比拟简洁,实用于字符串的编码。

`public void convertionString() throws UnsupportedEncodingException {
  String s = “ 愚公要移山,码农飞入地 ”;
  // 失常状况下转码的过程
  byte[] b = s.getBytes(“gbk”);// 编码
  String sa = new String(b, “gbk”);// 解码
  System.out.println(sa);
  // 谬误状态下转码的过程
  b = sa.getBytes(“utf-8”);// 编码应用 utf-8
  sa = new String(b, “gbk”);// 解码应用 gbk
  System.err.println(sa);
}
// 控制台输入:
// 愚公要移山,码农飞入地
// 鎰氬叕瑕佺Щ灞憋紝鐮佸啘椋炰笂澶?
`

3、Charset

`public void convertionCharset() throws IOException {
  Charset charset = StandardCharsets.UTF_8;
  // 从字符集中创立相应的编码和解码器
  CharsetEncoder encoder = charset.newEncoder();
  CharsetDecoder decoder = charset.newDecoder();
  // 结构一个 buffer
  CharBuffer charBuffer = CharBuffer.allocate(64);
  charBuffer.put(‘A’);
  charBuffer.flip();
  // 将字符序列转换成字节序列
  ByteBuffer bb = encoder.encode(charBuffer);
  // 将字节序列转换成字符序列
  bb.flip();
  CharBuffer cb = decoder.decode(bb);
}
`

以上就是三种根本的实现形式,当然还有一些其余的,比方 Spring 中提供的编码转换工具等等。在这里就不说了,因为技术太多,实现的形式也太多,咱们就看这几种即可。

正文完
 0