无法访问memoryStream的封闭Stream,如何重新打开?

oli*_*dev 35 c#

我有一个memoryStream实例,它已关闭.

我已经尝试过了:

memoryStream.Flush();
memoryStream.Position=0;
Run Code Online (Sandbox Code Playgroud)

要重新打开内存流但它不起作用.如何重新打开已关闭的内存流?

Gre*_*les 35

您可以克隆原始克隆,然后使用克隆,即使原始关闭也是如此.即使原始的创建容量为1000,ToArray()也会返回一个2元素数组.另一方面,ToBuffer()可以获得整个缓冲区,这是您不想要的.

MemoryStream original = new MemoryStream(1000);
original.WriteByte(4);
original.WriteByte(5);

MemoryStream dolly = new MemoryStream(original.ToArray());
dolly.Seek(0, SeekOrigin.Begin);
Run Code Online (Sandbox Code Playgroud)

  • 克隆是否复制缓冲区?或者只是指向相同的支持字节[]?我正在尝试从关闭的 MemoryStream 中获取 .Length (愚蠢的 API 认为编写 ** 并 ** 关闭流是件好事......) (2认同)

小智 15

试试这个:

memoryStream = new MemoryStream(memoryStream.ToArray());
Run Code Online (Sandbox Code Playgroud)


Ree*_*sey 12

如何重新打开已关闭的内存流?

您无法重新打开该流.如果您需要"重置"流,只需为其分配一个新实例:

memoryStream = new MemoryStream();
Run Code Online (Sandbox Code Playgroud)

  • 但是我如何重用封闭的内存流? (3认同)
  • 正如里德所说,你做不到.如果以后需要,请不要关闭它.如果您无法更改它已关闭的事实,则必须创建一个新的. (2认同)

Ren*_*Pet 9

这是一个古老的问题,但我正在回应这样一个事实,即接受的答案并不是真的有用,并且投票最高的答案说使用 .ToArray() 比使用 .GetBuffer() 更好。我认为在很多情况下,也许是大多数情况下,使用 .GetBuffer() 明显优于使用 .ToArray()。

这是一个尽管您希望继续使用内存流但仍然关闭的问题示例:

  /// <summary>
  /// Method that gets called by ManagedResource.WriteData() in project CodeAnalysis during code 
  /// emitting to get the data for an embedded resource file.
  /// </summary>
  /// <param name="resourceFullFilename">full path and filename for resource file to embed</param>
  /// <returns>MemoryStream containing .resource file data - caller will dispose it</returns>
  private static MemoryStream ProvideResourceData(string resourceFullFilename)
  {
     MemoryStream shortLivedBackingStream = new MemoryStream();
     using (ResourceWriter resourceWriter = new ResourceWriter(shortLivedBackingStream))
     {
        using (ResXResourceReader resourceReader = new ResXResourceReader(resourceFullFilename))
        {
           IDictionaryEnumerator dictionaryEnumerator = resourceReader.GetEnumerator();
           while (dictionaryEnumerator.MoveNext())
           {
              string resourceKey = dictionaryEnumerator.Key as string;
              if (resourceKey != null)  // Should not be possible
                 resourceWriter.AddResource(resourceKey, dictionaryEnumerator.Value);
           }
        }
     }

     return new MemoryStream(shortLivedBackingStream.GetBuffer());
  }
Run Code Online (Sandbox Code Playgroud)

这个ResourceWriter类需要一个支持流,所以我给它一个新创建的内存流。但是当ResourceWriter不再需要时,它会关闭后备流。然后我MemoryStream基于后备流的缓冲区创建一个新的缓冲区,即使它已关闭,它也能正常工作。

在这种情况下,我碰巧知道调用程序将使用提供的内存流将数据复制到另一个缓冲区,然后立即关闭内存流。所以,没有必要创建一个新的字节数组,并有性能优势不是建立一个新的字节数组。

感谢@JoshVarty 展示了如何避免在MemoryStream此处关闭的问题:https : //github.com/dotnet/roslyn/issues/7791