首先是把 0 ~19 20个(Int32类型,4个字节)的数字以二进制的形式写到一个文本文件中,我这测试用例为 F: test.txt ;
static void Main(string[] args)
{
//写入数据
string filePath;
Console.WriteLine("请输入需要创建的二进制文件路径(包括文件名)");
filePath = Console.ReadLine();
FileStream fileStream = new FileStream(filePath, FileMode.Create);
BinaryWriter writer = new BinaryWriter(fileStream);
for (int index = 0; index < 20; index++)
{
writer.Write(index);
}
Console.WriteLine("写入完毕");
writer.Close();
fileStream.Close();
}
接着以每2个字节(即Int16类型)来读取刚刚写入到 F:test.txt 的二进制文本文件。
Console.WriteLine("请输入文件名:");
string filePath = Console.ReadLine();
if (!File.Exists(filePath))
{
Console.WriteLine("文件不存在。");
}
else
{
FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(fileStream);
try
{
while (true)
{
Console.WriteLine(reader.ReadInt16());
}
}
catch (EndOfStreamException)
{
Console.WriteLine("已经到文件尾部了");
}
finally
{
reader.Close();
fileStream.Close();
Console.ReadKey();
}
}
上面的二段代码理解起来基本没有什么问题,按照我的常理:因为开始的时候是按每4个字节进行存储的,那么数据的存储顺序应该如下所示:
如果按照每2个字节进行读取的话,那么结果应该是:
是不是很吃惊呢?为啥会出现这种情况?这货是啥玩意?
于是,我很困惑,非常的困惑,碰到问题,就要解决问题,这是作为软件工程师最基本的要求,在网上找了很久,看的眼睛都花了,最后去CSDN论坛里问了下,坛子了说这与字节序有关,具体什么没有详说,于是拿出我的秘密武器:google. 当看到了字节序的有关概念,了解到数据在内存的排列方式后,这个问题就有解了。于是乎就有了这篇博文,下面我来解解这个问题。
在设计计算机系统的时候,有两种处理内存中数据的方法。一种叫为Little-Endian(小端),存放在内存中最低位的数值是来自数据的最右边部分(也就是数据的最低位部分)。与之相对于的是Big-Endian(大端),正好相反,存放在内存中最低位的数值是来自数据的最左边边部分(也就是数据的最高为部分),BIG-ENDIAN、LITTLE-ENDIAN、跟CPU有关的,每一种CPU不是BIG-ENDIAN就是LITTLE-ENDIAN、。IA架构(Intel、AMD)的CPU中是Little-Endian,而PowerPC 、SPARC和Motorola处理器是Big-Endian。这其实就是所谓的主机字节序(在张会勇的《winsock网络编程经络》中对于主机字节序与网络字节序,也就是这里的大端和小端的名称是一个意思,那书上有详细的介绍,你可以看看)。大部分的人使用的是IA架构的计算机,包括笔者我的本本。可能对于这样的解释有些人还是有些迷惑,下面就以Int32类型的 数字1 为列,分别以Little-Endian 和Big-Endian 来介绍其在内存中的存储顺序。
Little-Endian:将低序字节存储在起始地址
int32类型的数字1其二进制表示为:
则其按照Little-Endian 方式进行数据存储的话,则其在内存中的排列方式为:
即数值在内存中的存储顺序与其二进制表示有点不同,所有如果我按照每2个字节(即int16类型)进行读取的话,取到的数据应该是 1 0 ,正好与结果相吻合。至于之所以这样设计是为了方便计算机处理数据,提供效率。我的机器就是以Little-Endian方式对数据进行存储的。
Big-Endian: 将高序字节存储在起始地址
理解了Little-Endian 的排列方式,那么Big-Endian就不难理解了。下为int32类型的数字1在内存中以Big-Endian方式进行排列图: