C# 温故而知新:Stream篇(五)
MemoryStream
目录:
1 简单介绍一下MemoryStream
2 MemoryStream和FileStream的区别
3 通过部分源码深入了解下MemoryStream
4 分析MemorySteam最常见的OutOfMemory异常
5 MemoryStream 的构造
6 MemoryStream 的属性
7 MemoryStream 的方法
8 MemoryStream 简单示例 : XmlWriter中使用MemoryStream
9 MemoryStream 简单示例 :自定义一个处理图片的HttpHandler
10 本章总结
简单介绍一下MemoryStream
MemoryStream是内存流,为系统内存提供读写操作,由于MemoryStream是通过无符号字节数组组成的,可以说MemoryStream的性能可以
算比较出色,所以它担当起了一些其他流进行数据交换时的中间工作,同时可降低应用程序中对临时缓冲区和临时文件的需要,其实MemoryStream
的重要性不亚于FileStream,在很多场合我们必须使用它来提高性能
MemoryStream和FileStream的区别
前文中也提到了,FileStream主要对文件的一系列操作,属于比较高层的操作,但是MemoryStream却很不一样,它更趋向于底层内存的操作,这样
能够达到更快的速度和性能,也是他们的根本区别,很多时候,操作文件都需要MemoryStream来实际进行读写,最后放入到相应的FileStream中,
不仅如此,在诸如XmlWriter的操作中也需要使用到MemoryStream提高读写速度
通过部分源码深入了解下MemoryStream
由于篇幅关系,本篇无法详细说明其源码,还请大家海涵,这里我就简单介绍下Write()方法的源码- public override void Write(byte[] buffer, int offset, int count) {
- if (!_isOpen) __Error.StreamIsClosed();
- if (!_writable) __Error.WriteNotSupported();
- if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
-
- int i = _position + count;
- // Check for overflow
- if (i < 0)
- throw new IOException(Environment.GetResourceString("IO.IO_StreamTooLong"));
- if (i > _length) {
- bool mustZero = _position > _length;
- if (i > _capacity) {
- bool allocatedNewArray = EnsureCapacity(i);
- if (allocatedNewArray)
- mustZero = false;
- }
- if (mustZero)
- Array.Clear(_buffer, _length, i - _length);
- _length = i;
- }
- if (count <= 8)
- {
- int byteCount = count;
- while (--byteCount >= 0)
- _buffer[_position + byteCount] = buffer[offset + byteCount];
- }
- else
- Buffer.InternalBlockCopy(buffer, offset, _buffer, _position, count);
- _position = i;
- return;
- }
复制代码 关于MemoryStream的源码大家可以自己学习,这里主要分析下MemoryStream最关键的Write()方法,自上而下,最开始的一系列判断大家很容易看明白,
以后对有可能发生的异常应该了如指掌了吧,判断后会取得这段数据的长度 int i=_position+count ,接下来会去判断该数据的长度是否超过了该流的长度,
如果超过再去检查是否在流的可支配容量(字节)之内,(注意下EnsureCapacity方法,该方法会自动扩容stream的容量,但是前提条件是你使用了memoryStream
的第二个构造函数,也就是带有参数是Capaciy)如果超过了流的可支配容量则将尾巴删除(将超过部分的数据清除),接下来大家肯定会问,为什么要判断count |