积极答复者
MemoryStream反编译代码为何不超过索引?

问题
-
为了更好地了解MemoryStream的原理,我使用最新的Reflector反编译查看Write方法,其中关键如下:
[SecuritySafeCritical]
public override void Write(byte[] buffer, int offset, int count)
{
………………………… //此处省略
int num = this._position + count;
if (num < 0)
{
throw new IOException(Environment.GetResourceString("IO.IO_StreamTooLong"));
}
if (num > this._length)
{
bool flag = this._position > this._length;
if ((num > this._capacity) && this.EnsureCapacity(num))
{
flag = false;
}
if (flag)
{
Array.Clear(this._buffer, this._length, num - this._length);
}
this._length = num;
}
if ((count <= 8) && (buffer != this._buffer)) //第一问:为什么要判断count<=8?
{
int num2 = count;
while (--num2 >= 0)
{
this._buffer[this._position + num2] = buffer[offset + num2];
//第二问(注意我下面的问题和代码)——
}
}
else
{
Buffer.InternalBlockCopy(buffer, offset, this._buffer, this._position, count);
}
this._position = num;
}
【第二问】
现在假设我这样调用代码:
byte[] bytes = new byte[8];
MemoryStream ms = new MemoryStream(bytes,0,bytes.Length,true,true);
ms.Write(new byte[] { 1, 2, 3 }, 1, 2);那么执行到粗体部分的“第二问”的时候offset=1,count=2。那么buffer[3],这里的buffer既然是new byte[]{1,2,3}……为什么没有出现溢出错误呢?明明总数只有3个,因此最大的索引应该是2啊?
请教了!谢谢!
答案
-
首先,//第一问:为什么要判断count<=8? 我个人认为8 byte在内存中代表着十分重要的东西,比如说内存地址。Byte通常作为计算机的信息计量单位,但是这里用8可能是出于性能的考虑和设计的需要,因为从代码上看,当要向内存中写入的byte数小于等于8的时候,是一个byte一个byte写入内存的。 当大于8时, 该方法调用的是其他方法——InternalBlockCopy,这个方法的原型是C++代码,也是处理内存写入的。
然后是第二问,我觉得您应该首先明白的是count代表的是什么意思。MSDN文档上说的是count代表最多写入的字节数。MemoryStream.Write 方法 (System.IO) 也就是说当您设置为2,offset偏移量为1的时候,不管您的buffer是多长,只会向内存中写入前2个byte,也就是buffer[0]和buffer[1].
分析一下代码:虽然buffer的长度是3, 但是在执行到
int num2 = count; //以下循环一共执行2次。 while (--num2 >= 0)//首先num2先减1, { this._buffer[this._position + num2] = buffer[offset + num2];//第一次循环,offset=1,num2 =1, 第二次循环,offset=1,num2 =0. } }
的时候,num2 = 2, 但是到第一次while循环里,buffer[offset =1+ 1]其实是buffer[2],我想您指的索引应该是说count为2,可能您需要详细的参考一下MSDN文档。
希望以上的内容对您有所帮助。
Best Regards,
Rocky Yue[MSFT]
MSDN Community Support | Feedback to us
- 已编辑 Lie YouModerator 2012年2月1日 7:51
- 已标记为答案 ThankfulHeartModerator 2012年2月2日 2:33
全部回复
-
首先,//第一问:为什么要判断count<=8? 我个人认为8 byte在内存中代表着十分重要的东西,比如说内存地址。Byte通常作为计算机的信息计量单位,但是这里用8可能是出于性能的考虑和设计的需要,因为从代码上看,当要向内存中写入的byte数小于等于8的时候,是一个byte一个byte写入内存的。 当大于8时, 该方法调用的是其他方法——InternalBlockCopy,这个方法的原型是C++代码,也是处理内存写入的。
然后是第二问,我觉得您应该首先明白的是count代表的是什么意思。MSDN文档上说的是count代表最多写入的字节数。MemoryStream.Write 方法 (System.IO) 也就是说当您设置为2,offset偏移量为1的时候,不管您的buffer是多长,只会向内存中写入前2个byte,也就是buffer[0]和buffer[1].
分析一下代码:虽然buffer的长度是3, 但是在执行到
int num2 = count; //以下循环一共执行2次。 while (--num2 >= 0)//首先num2先减1, { this._buffer[this._position + num2] = buffer[offset + num2];//第一次循环,offset=1,num2 =1, 第二次循环,offset=1,num2 =0. } }
的时候,num2 = 2, 但是到第一次while循环里,buffer[offset =1+ 1]其实是buffer[2],我想您指的索引应该是说count为2,可能您需要详细的参考一下MSDN文档。
希望以上的内容对您有所帮助。
Best Regards,
Rocky Yue[MSFT]
MSDN Community Support | Feedback to us
- 已编辑 Lie YouModerator 2012年2月1日 7:51
- 已标记为答案 ThankfulHeartModerator 2012年2月2日 2:33