.NET MemoryStream似乎没有.Reset或.Clear方法。
我在考虑使用以下代码来完成此任务:
ms.Seek(0, IO.SeekOrigin.Begin)
ms.SetLength(0)
清除或重置现有.NET MemoryStream的正确方法是什么?
答案 0 :(得分:68)
为什么需要重置内存流?你总能创造一个新的。或者您可以使用:
memoryStream.SetLength(0);
答案 1 :(得分:20)
由于MemoryStream本质上是一个带索引的字节数组(以及一些其他支持成员),因此清除字节数组并重置索引可以被视为重置和清除MemoryStream。如果MemoryStream的初始状态是位置为零的归零数组,那么MemoryStream重置的示例可能是:
public static void Clear(this MemoryStream source)
{
byte[] buffer = source.GetBuffer();
Array.Clear(buffer, 0, buffer.Length);
source.Position = 0;
source.SetLength(0);
}
说MemoryStream.SetLength单独重置或清除MemoryStream是不正确的,因为如果长度超过当前缓冲区的长度,SetLength只会清除内部缓冲区数组。
重新初始化MemoryStream是一种有效的方法,但效率较低。重新初始化MemoryStream的一个好处是保证流永远不会关闭。关闭MemoryStream后,将无法再更改它。如果您可以确保MemoryStream实例未关闭,那么清除缓冲区可能就好了。
答案 2 :(得分:3)
内存流没有重置/清除方法,因为它是多余的。通过将其设置为零长度,您可以清除它。
当然你总能做到:
memoryStream = new MemoryStream(memoryStream.Capacity());
这会产生一个与初始化相同大小的内存流。
如果你真的想要手动清除流,我怀疑你不得不求助于遍历这些元素。
答案 3 :(得分:0)
我使用 DotMemory 来配置文件@Rana_Ian解决方案,然后我打电话给GC强制执行完整收集。 我发现大型流将卡在 LOH 中! 然后再添加一行
public static void Clear(MemoryStream ms)
{
var buffer = ms.GetBuffer();
Array.Clear(buffer, 0, buffer.Length);
ms.Position = 0;
ms.SetLength(0);
ms.Capacity = 0; // <<< this one ******
}
我点击了 F12 以查看Capacity
的实现,然后发现了这一点(我简化了生成的代码):
public virtual int Capacity
{
get
{ .... // some code }
set
{
if ((long) value < this.Length) { // throw some ex }
if (!this._isOpen) { // some another code }
if (!this._expandable && value != this.Capacity) { //MemoryStreamNotExpandable }
if (!this._expandable || value == this._capacity) return;
if (value > 0)
{
byte[] numArray = new byte[value];
if (this._length > 0)
Buffer.InternalBlockCopy((Array) this._buffer, 0, (Array) numArray, 0, this._length);
this._buffer = numArray;
}
else
this._buffer = (byte[]) null; /// <<<< that's it! I need this one
this._capacity = value;
}
}
所以它正在清除缓冲区,我不确定这是正确的还是注意!