当前位置: 首页 > 科技观察

你知道Java的几种编码方式吗?解决乱码问题可能就不麻烦了

时间:2023-03-16 12:18:27 科技观察

前言编码的转换通常用在IO机制中。一个好的编码可以为我们节省很多空间,一定程度上可以提高我们应用的效率。由于之前知道String中的转换方式,也有一些工具,所以今天整理一下jdk在java中提供的几种转换方式,希望对大家有所帮助。一、编码转换的原理1、为什么需要编码我们知道,计算机存储信息的最小单位是一个8位的字节,可以表示256个字符。这对于早期英语来说已经足够了。甚至添加一些常用符号就足够了。于是在1965年,美国制定了ASCII码,主要用于英语和西欧语言。一开始是128,后来加到256。后来随着时间的发展,中国、日本等国的计算机也开始蓬勃发展,于是计算机不仅要存英文,还开始存中文。但是我们都知道,几万个中文太多了,一个字节肯定放不下。我应该怎么办?如果一个字节表达不出来,就多用几个字节。这样既可以表示汉字,又可以避免与ASCII编码冲突。这些字节在存储的时候都转换成了比特,完美!关键是编码解决了字节和字符之间的转换问题。2、编码方式既然是编码,那些大佬们早就考虑到这些问题了,提出了多种编码方式,常见的有ASCII、ISO-8859-1、GB2312、GBK、UTF-8、UTF-16、ETC。。他们规定了转换规则,根据这个规则,计算机就可以正确地表示我们的字符。GB2312、GBK、UTF-8、UTF-16等多种方式都可以表示汉字。它们之间有什么区别?(1)GB2312为双字节编码,总编码范围为A1-F7。-A9为符号区,共包含682个符号,B0-F7为汉字区,共包含6763个汉字。这是1981年在中国创造的。这种编码是一个汉字两个字节。(2)GBK的编码范围为8140~FEFE(去掉XX7F),共有23940个码位,可表示21003个汉字。这是中国在1995年开发的,主要作为GB2312编码的补充。这个编码还是一个汉字两个字节。(3)Unicode上面看到,中国可以制一个码,日本也可以制一个码。时间久了,每个国家都有自己的一套法典,难免会产生冲突。于是Unicode就出来了,把所有的语言统一为一个规则。这种编码是固定长度的字节数。(4)UTF8由于Unicode是固定长度的字节数,存储一个复杂的汉字可能需要3个字节,但为了保证是2的幂集,会自动扩充为4个字节,别看是一个字节的差异,如果存储的字数太多,会浪费很多空间。因此,UTF-8采用变长技术,每个编码区的字长不同。不同类型的字符可以由1~6个字节组成。以上编码方式都会为每一个汉字或字母创建一个编码库,编码时字母和编码一一对应。3、为什么会出现乱码?这个问题是因为编码和解码使用不同或不兼容的编码方案。例如,以UTF-8编码的字符。然后用GBK解码,因为两个字符集的编码库不一样。同一个汉字在两个编码库中的位置也不一样。于是就出现了乱码。4、java如何解决乱码问题?这个问题其实就是java中如何使用编码规则,因为编码规则用的很好。只有这样才能很好的解决乱码问题。(1)IO流编码的目的上面已经说了,主要是字节和字符之间的转换。既然容易涉及到字节和字符,那么我们可以想到java中的IO流。也就是说,java中编码的转换实际上是由IO流中的类来实现的。核心就是上面的类。当然这里只给出了部分输入,还有一些输出类。(2)StringString类中也提供了一些转码方法。下面我们将举例说明。为什么String可以实现?这是因为String的底层其实就是一个字节,而String也有直接转换成字符的方法。所以String一定是可以实现的。(3)Charset这个Charset是javaNIO中的一个类。整个过程就是读取数据,然后转换成byte,也就是字符。然后重新编码成字符就OK了。下面我们用代码来实现一下:二、代码实现1、IO流首先由IO流实现,可以直接通过输入输出流指定编码规则。publicvoidconversionFile()throwsIOException{Filefile=newFile("./愚公想搬山.txt");FileInputStreamfis=newFileInputStream(file);InputStreamReaderinReader=newInputStreamReader(fis,"gbk");FileOutputStreamfos=newFileOutputStream(Readfile);OutputStreamWriterOut=newFileOutputStreamWriterout(fos,"utf-8");//这种输入gbk,输出utf-8肯定会出错}2.String用string最方便,代码也比较简洁,就是适用于字符串的编码。publicvoidconvertionString()throwsUnsupportedEncodingException{Strings="愚公移山,码农飞上天";//正常情况下转码的过程byte[]b=s.getBytes("gbk");//编码Stringsa=newString(b,"gbk");//解码System.out.println(sa);//错误状态下转码的过程b=sa.getBytes("utf-8");//编码使用utf-8sa=newString(b,"gbk");//解码使用gbkSystem.err.println(sa);}//控制台输出://愚公欲移山,码农飞上天//镒阿叐佺佺ЩBa呼3。CharsetpublicvoidconvertionCharset()throwsIOException{Charsetcharset=StandardCharsets.UTF_8;//从字符集创建对应的编码和解码器CharsetEncoderencoder=charset.newEncoder();CharsetDecoderdecoder=charset.newDecoder();//构造一个缓冲区CharBuffercharBuffer=CharBuffer.allocate(64);charBuffer.put('A');charBuffer.flip();//将字符序列转换成字节序列ByteBufferbb=encoder.encode(charBuffer);//将字节序列转换为字符序列bb.flip();CharBuffercb=decoder.decode(bb);}以上就是三种基本的实现方式,当然还有一些其他的,比如Spring中提供的编码转换工具等,这里就不说了,因为还有太多的技术和实现它们的方法太多了,所以我们只看这几种。本文转载自微信公众号“愚公要移山”,可关注下方二维码。转载本文请联系愚公移山公众号。