字节序
字节顺序,又称之为:端序 或 尾序。在计算机科学领域中指的是:电脑内存 或者在网络通讯链路中,由多个字节组成的字的排列方式。
由于不同架构的CPU处理多个字节数据的顺序不一样,比如x86的是小段端模式,KEIL C51是大端模式。但是后来互联网流行,TCP/IP协议规定为大端模式,又称为:network order。
大端和小端
在计算机体系中我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。
在编程语言中一个long类型占32bit,那就需要4个字节来存储,那按照什么样的顺序将这四个字节写到内存中?
因此就出现了大端存储模式和小端存储模式。
大端(Big-Endian):  数据的高位字节在前(内存的低地址),低位字节在后。这样的存储模式类似于把数据当做字符串处理,内存地址由小到大增长,而数据从高位字节开始写入。  
这种方式符合人类的阅读习惯!
小端(Little-Endian): 数据的低位字节在前(内存的低地址),高位字节在后。这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。
示例:
如:
32位的16进制数:0x1A2B3C4D  在内存中的存储
1 2 3 4
   | 内存地址: 00  01  02  03 ------------------------------ 小端模式: 4D  3C  2B  1A 大端模式: 1A  2B  3C  4D
   | 
 
java中的大端和小端
Java二进制文件中的所有内容均按大端顺序存储。这种存储方式也被称为network order。这意味着,如果仅仅是用java,则在所有的平台上(如Mac、 PC、 UNIX等)
所有文件的处理方式都相同,可以自由的进行二进制文件的交换,而无需担心字节顺序的问题。  
java对我们隐藏了内部字节顺序的问题!
但是当我们与某些不是用Java编写的使用小端顺序的程序交换数据文件时,就会出现问题。最常见的是使用C编写的程序。某些平台在内部使用大端顺序(Mac,IBM 390),有些使用小端序(Intel)。  
C语言默认是小端模式。
如果java 要读取C 写的二进制文件,就要涉及到大小端转换的问题。
java代码测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
   |  public static void printSystemInfo() { 	System.out.println("##########################################"); 	System.out.println("系统名称:" + System.getProperty("os.name")); 	System.out.println("系统架构:" + System.getProperty("os.arch")); 	System.out.println("系统版本:" + System.getProperty("os.version")); 	System.out.println("##########################################"); 	System.out.println(""); }
  public static Unsafe getUnsafe() throws Exception { 	Field f = Unsafe.class.getDeclaredField("theUnsafe"); 	f.setAccessible(true); 	Unsafe unsafe = (Unsafe) f.get(null); 	return unsafe; }
  public static void main(String[] args) throws Exception { 	printSystemInfo(); 	try { 		Unsafe UNSAFE = getUnsafe();
  		int intVal = 0x1A2B3C4D; 		System.out.println("原始值:十六进制:" + Integer.toHexString(intVal) + "  对应十进制:" + intVal);
  		// 分配4个字节的内存 		long address = UNSAFE.allocateMemory(4); 		// 存放int类型的数据,占4个字节 		UNSAFE.putInt(address, intVal); 		byte b = UNSAFE.getByte(address); 		// 通过getByte方法获取刚才存放的int,取第一个字节 		// 如果是大端,存放顺序 —> 1A,2B,3C,4D,取第一位便是0x1A 		// 如果是小端,存放顺序 —> 4D,3C,2B,1A ,取第一位便是0x4D 		System.out.println("取到的第一个字节:" + Integer.toHexString(b)); 		ByteOrder byteOrder; 		switch (b) { 			case 0x1A: 				System.out.println("当前使用:大端序"); 				byteOrder = ByteOrder.BIG_ENDIAN; 				break; 			case 0x4D: 				System.out.println("当前使用:小端序"); 				byteOrder = ByteOrder.LITTLE_ENDIAN; 				break; 			default: 				byteOrder = null; 		} 		System.out.println(byteOrder); 		// 这里在X86架构的windows机器上跑,输出结果为: 		// LITTLE_ENDIAN
  		// 然后我们重新从内存中读取int 		int val2 = UNSAFE.getInt(address); 		System.out.println("重新从内存中读取的值:" + val2); 	} catch (Exception e) { 		e.printStackTrace(); 	} }
 
  | 
 
输出结果
window平台
1 2 3 4 5 6 7 8 9 10 11
   | ########################################## 系统名称:Windows 7 系统架构:amd64 系统版本:6.1 ##########################################
  原始值:十六进制:1a2b3c4d  对应十进制:439041101 取到的第一个字节:4d 当前使用:小端序 LITTLE_ENDIAN 重新从内存中读取的值:439041101
   | 
 
linux平台
1 2 3 4 5 6 7 8 9 10 11
   | ########################################## 系统名称:Linux 系统架构:amd64 系统版本:2.6.32-642.el6.x86_64 ##########################################
  原始值:十六进制:1a2b3c4d  对应十进制:439041101 取到的第一个字节:4d 当前使用:小端序 LITTLE_ENDIAN 重新从内存中读取的值:439041101
   |