前面在了解字符编码的时候,遇到了为什么UTF-8
没有字节序的问题,这个字节序是什么?为什么UTF-16
会有字节序的问题呢?
字节序是什么
首先,需要明白的是,由于各种历史原因,不同的CPU
存储的处理一个多字节数据的方式是不一样的:
- 大端字节序(
big endian
):高位字节在前,低位字节在后,比如两个字节中:1234 5678 ,大端字节序CPU
会处理为一千两百三十四 万 五千六百七十八 - 小端字节序(
little endian
):低位字节在前,高位字节在后,同样比如:1234 5678, 小端字节序CPU
会处理为五千六百七十八 万 一千两百三十四
其实,需要补充明白的是,虽然有字节序的概念,但是这仅仅是在处理多字节数据才会存在的问题,比如double
,long
这种一个字节无法存放的数据。字节序并不会影响数据的整体顺序,比如我存放一条文本:我们,并不会因此字节序不同的原因变为们我,对于任何cpu
来说,字节序对于用户来说都是透明的,这也是为什么我们常常编程,但是很少会遇到字节序的问题。
为什么会有字节序的问题
有人可能就会说了,为什么非要有字节序的问题,都规定好cpu
读取数据的顺序,就不会这么复杂了。确实如此,但是不同的字节序会导致cpu
处理数据的性能不同,比如:
- 对于小端
cpu
来说,计算加法会更方便,但是对于常用除法的cpu
来说,还是大端好 - 对于小端
cpu
来说,强制转换数据类型不用调整字节的内容,1,2,4字节的存储方式都一样,但是对于大端来说,符号位的判断为固定第一个字节,更加容易判断正负 - 。。。
因此,一般来说,x86
,Z80
等处理器一般是小端序,而Motorola 6800
等处理器为大端序,还有一类入ARM,PowerPC
是可以手动配置的。
怎么避免字节序的问题
前面说过,一般来说字节序的问题对于用户来说,是透明的,对于同一台电脑,同一种语言,是永远不会出现字节序的问题,想要避免字节序的问题,要明白什么时候会因为字节序带来问题:
当两个系统处理的字节序有可能不同的时候
看着像废话,但是道理确实是这样。
比如C/C++
语言的字节序是依赖于编译平台所在的CPU,而对于Java来说,是规定使用大端序,而这个时候如果Java系统存储一个多字节数据之后,再使用C++
去相同的内存读取,可能就会出现问题。
同理的还有就是常说的网络字节序,因为TCP/IP
协议规定socket
通过TCP/IP
协议传送字节的时候,统一使用大端序,这样对于那些使用小端序的操作系统来说,就需要进行本地字节序和网络字节序相互转换。
这里再回到文章开篇的问题,为什么UTF-16
会有大端序,小端序之分,因为UTF-16
处理单元为2字节,就好像long
,double
,而如果不规定大端序和小端序,那么如果一个字符,先通过使用小端序的程序保存,然后再使用其他使用大端序的程序读取,读取的数据可能就会有很大的不同。
而为什么UTF-8
没有这个问题呢?最主要的原因是UTF-8
处理单位为一个字节。况且UTF-8
每个字节都标明了顺序。