你真的明白Java和Python3使用Unicode编码的含义吗?

经常会听到Unicode是用两个字节表示世界上所有语言的编码,那么问题来了两个字节不过65535个符号,怎么能表示所有语言?也经常搞不清楚Unicode和UTF-8到底有什么区别。也曾听说内存中都是Unicode统一表示,然后传输和存储的时候转换成UTF-8。总之网络时代就是这样——众说纷纭。这里,我仅把此刻认为正确的说法记录下来。

一. Unicode

世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。为什么电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。

可以想象,如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是 Unicode,就像它的名字所表示的,这是一种所有符号的编码。

Unicode 当然是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母AinU+0041表示英语的大写字母AU+4E25表示汉字。具体的符号对应表,可以查询unicode.org,或者专门的汉字对应表

需要注意的是,Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

比如,汉字的 Unicode 是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说,这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。所以到这里,我们可以明确的指出,Unicode是用两个字节表示字符这种说法是错误的。

误区:java使用Unicode编码,所以一个汉字用两个字节表示。

来解释一下,首先明确java使用Unicode编码的意思,所谓的java使用Unicode编码其实是一个比较复杂的事情,说来话真的很长。

比如说,我们在.java源文件中申请一个字符串 String str = "中文"; 那么当这个.java文件被运行起来的时候,str在内存中为了表示"中文"这两个汉字就会有一个对应的值,而这个对应的值使用的是Unicode编码规则对应的。

但是,我们上面指出了,Unicode编码里中文并不是两个字节,可能是更多字节来表示的,那么java是怎么做到只用两个字节来表示一个中文的?

其实,正确来讲,java使用Unicode编码,准确来说其实是使用UTF-16,一个中文字符绝大多数情况下都是两个字节。

这里就有必要说一下UTF

二.UTF

UNICODE 来到时,一起到来的还有计算机网络的兴起,UNICODE 如何在网络上传输也是一个必须考虑的问题,于是面向传输的众多 UTF(UCS Transfer Format)标准出现了。为什么会出现?因为如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。

所以,本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间。

再说UTF-16,即把Unicode字符集的抽象码位映射为16位长的整数(即码元)的序列,用于数据存储或传递。UTF-16 使用二或四个字节为每个字符编码,其中大部分汉字采用两个字节编码,少量不常用汉字采用四个字节编码。 

误区:内存和传输、存储使用的是一种编码

搞清楚了Unicode和UTF-8的关系,我们就可以总结一下现在计算机系统通用的字符编码工作方式:

在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。

用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件:

rw-file-utf-8

浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器:

 

搞清楚UTF-8解决的问题和一种语言所使用的编码(内码)是什么意思,对上面的说法就很容易理解

首先UTF出现就是为了在网络上传输和存储中使用的,因此硬盘上或传输流上使用UTF-8没有问题。

那么为什么内存中要统一使用一种编码呢?其实也很简单:.java源码文件这个文件本身也是有编码的,不同.java源文件这个编码可以不同,当JVM去编译这个源文件的时候,根据这个编码去识别才能够正确编译出.class文件,并且把它们统一编码成UTF-16在JVM中运行才不会因为各个源文件编码不同而出错。

因此,同样的道理,浏览网页的时候,服务器也用这种思路统一以Unicode编码去运行程序,然后用UTF-8去传输。

 

最后在编写程序中的例子去理解

例子链接

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java和Python都内置了处理编码问题的工具。 在Java中,字符串是使用Unicode字符编码的,因此Java提供了许多用于将字符串转换为不同编码格式的类和方法,例如String.getBytes()和new String(byte[], Charset)等。 而在Python中,字符串也是使用Unicode字符编码的,但是Python的字符串是可变的,因此Python提供了许多用于编码和解码字符串的方法和模块,如encode()和decode()方法、codecs模块等。 这些内置的工具可以帮助我们在处理不同编码格式的数据时更加方便和高效。 ### 回答2: Java和Python都是常用的编程语言,它们提供了自带处理编码问题的工具。这些工具的意思是它们可以帮助程序员在处理不同编码方式的数据时更加方便和有效。 在Java中,Java提供了java.nio.charset包来处理编码问题。通过使用该包中的类,如Charset和CharsetEncoder,程序员可以将文本从一种编码转换为另一种编码,或者验证特定编码是否支持。Java还提供了一些用于处理读取和写入文本文件时的编码问题的类,如InputStreamReader和OutputStreamWriter。 在Python中,Python的内置模块codecs提供了处理编码问题的工具。使用codecs模块,程序员可以更方便地处理不同编码方式的数据。codecs模块中的函数和类可以用于将文本从一种编码转换为另一种编码,或者用于读取和写入不同编码方式的文本文件。 总的来说,Java和Python提供的自带处理编码问题的工具使得程序员可以更轻松地处理不同编码方式的数据。这些工具可以帮助程序员转换编码、验证编码是否支持,以及读取和写入不同编码方式的文本文件,从而提高编码相关任务的效率和准确性。 ### 回答3: Java和Python都有自带的处理编码问题的工具。所谓的处理编码问题的工具,是指这两种编程语言内置的功能或库,用于解决字符编码方面的各种问题。 在Java中,处理编码问题的工具主要是通过内置的 java.nio.charset 包来实现的。这个包提供了一套用于字符编码和解码的类和接口,包括 Charset、CharsetDecoder、CharsetEncoder等。通过这些类,Java可以方便地进行字符编码和解码的转换,包括将字符串按照不同的字符编码方式存储、读取和输出。 而在Python中,处理编码问题的工具则是通过内置的 unicode 类型和相应的字符串方法来实现的。Python的字符串可以是Unicode字符串,这意味着它们可以表示任何Unicode字符。此外,Python还提供了编码和解码相关的方法,如encode()和decode(),可以在不同的字符编码方式之间进行转换。 总之,无论是Java还是Python,它们都提供了内置的工具来处理编码问题,使用户能够更加方便地进行字符编码的转换和处理,确保程序在不同编码环境下的正确运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值