重置或清除.NET MemoryStream

kuarbcqp  于 2023-06-25  发布在  .NET
关注(0)|答案(5)|浏览(190)

.NET MemoryStream似乎没有.Reset或.Clear方法。
我想用下面的代码来实现这一点:

ms.Seek(0, IO.SeekOrigin.Begin)
ms.SetLength(0)

清除或重置现有.NET MemoryStream的正确方法是什么?

bkkx9g8r

bkkx9g8r1#

为什么需要重置内存流?你总是可以创造一个新的。或者您可以用途:

memoryStream.SetLength(0);
7xzttuei

7xzttuei2#

由于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示例没有关闭,那么清除缓冲区可能是一种方法。

e4yzc0pl

e4yzc0pl3#

我使用DotMemory来配置@Rana_Ian解决方案,并调用GC强制执行完全收集。我发现大会卡在!在多加了一行之后

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实现,我发现了这个(我简化了一点生成的代码-我使用Resharper):

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;
  }
}

所以它的清除缓冲区,我不知道这是正确的或不!

ldxq2e6h

ldxq2e6h4#

:)你可以像这样创建你的内存流:

public class ResettableMemoryStream : MemoryStream
{
    public void Reset()
{
    Seek(0, SeekOrigin.Begin);
}
}

在你的代码调用中的操作之后:return();

w46czmvw

w46czmvw5#

内存流没有reset/clear方法,因为它是多余的。通过将其设置为零长度,可以清除它。
当然,你总是可以这样做:

memoryStream = new MemoryStream(memoryStream.Capacity());

这将产生与初始化大小相同的内存流。
如果您真的想手动清除流,我怀疑您将不得不求助于循环元素。

相关问题