C#中流复制与流转换的差异及两段代码性能对比
Stream转字节数组两种实现的差异、效果与性能分析
一、两段代码的主要差异
- 适用范围不同:第一段的
CopyTo方案支持所有Stream子类(如FileStream、NetworkStream、MemoryStream等),无需关心原流的具体类型;第二段的强制转换仅在原流实际是MemoryStream实例时有效,否则会抛出InvalidCastException。 - 内存与数据处理逻辑不同:第一段会创建新的MemoryStream,将原流数据完整复制到新流中再生成字节数组——相当于额外占用一份与原流数据大小相同的内存;第二段直接复用原MemoryStream的内部缓冲区,不会额外分配复制数据的内存(仅在调用
ToArray时生成数组副本)。 - 对原流状态的影响不同:第一段执行
CopyTo前需确保原流Position处于起始位置(否则仅复制当前位置到末尾的内容),复制后原流Position会停在末尾;第二段强制转换后,调用ToArray不会改变原流的Position,但后续对原流的读写会直接影响该MemoryStream的内容。
二、直接类型转换的效果是否和流复制一致?
并不完全一致,分两种场景:
- 原流是MemoryStream时:若原流
Position在起始位置,两者最终得到的字节数组内容相同,但第一段多了一次数据复制操作;若原流Position不在起始位置,第一段若未重置Position,只会复制部分内容,而第二段调用ToArray始终返回流的全部数据,此时结果完全不同。 - 原流不是MemoryStream时:第二段直接抛出类型转换异常,无法完成转换;第一段仍能正常复制数据并生成字节数组。
三、第二段代码的性能是否更优?
仅在原流确实是MemoryStream且转换成功的前提下,第二段性能更优:
- 第二段无需额外创建MemoryStream和复制数据,仅调用
ToArray生成一次数组副本,内存开销和CPU消耗远低于第一段; - 第一段需要完成「创建新流→复制数据→生成数组」三步操作,内存占用是第二段的两倍左右,数据复制也会带来额外的CPU开销。
但如果原流不是MemoryStream,第二段直接报错,不存在性能对比的意义,此时第一段是唯一可行的方案。
内容的提问来源于stack exchange,提问作者Aneesh Narayanan
相关产品推荐
相关产品推荐

