C# “我该怎么做?”;叉子;NET中的流?

C# “我该怎么做?”;叉子;NET中的流?,c#,stream,clone,memorystream,C#,Stream,Clone,Memorystream,正如,当BinaryReader或BinaryWriter关闭时,其底层流也会关闭(aargh)。考虑这种情况:例程 r>代码>通过内存流,比如“代码> M < /代码>;我想在M中编写一些东西,然后将其传递给另一个例程进行更多处理(不一定是编写)。为了方便起见,我想将M包装在BinaryWriter中进行编写。在编写之后,我已经完成了BinaryWriter,但没有使用m void R(MemoryStream M) { using (B = new BinaryWriter(M))

正如,当BinaryReader或BinaryWriter关闭时,其底层流也会关闭(aargh)。考虑这种情况:例程<代码> r>代码>通过内存流,比如“代码> M < /代码>;我想在
M
中编写一些东西,然后将其传递给另一个例程进行更多处理(不一定是编写)。为了方便起见,我想将
M
包装在BinaryWriter中进行编写。在编写之后,我已经完成了BinaryWriter,但没有使用
m

void R(MemoryStream M)
{
    using (B = new BinaryWriter(M))
    {
        // write some stuff using B
    }

    S(M);  // now pass M to another routine for further processing
}
但是,如果不关闭
M
,我就无法处理二进制流

void R(MemoryStream M)
{
    using (B = new BinaryWriter(M))
    {
        // write some stuff using B
    }

    S(M);  // now pass M to another routine for further processing
}
问:有没有办法做到以下几点

  • 从MemoryStream中提取基础字节[]
  • 克隆流
  • 关闭后重新打开流

    • 一种有点幼稚的方法是使用

      byte buf[] = MemoryStream.ToArray();
      
      将流内容复制到字节数组。你可以把它变成一条小溪

      MemoryStream ms = new MemoryStream(buf);
      
      你可以:

      • 调用M.ToArray()以获取字节数组形式的流
      • 子类BinaryWriter并重写Dispose方法以防止关闭子流

      根据M.Clone();应该有用。但是我可能错了…

      您最好使用

      byte[] buffer = ms.GetBuffer();
      
      然后使用Array.copy()方法复制字节数据。
      您可以使用它自由创建一个新流。

      多亏了几个人的建议,我找到了正确的答案,即“M.GetBuffer”。ToArray还不算太糟,但它

      • 复制
      • 仅获取缓冲区的一部分

      GetBuffer只是获取一个对底层字节[]的引用,这正是我想要的。

      您可以使用中的
      MiscUtil.IO.NonClosingStreamWrapper
      之类的东西,它包装
      ,并简单地忽略
      关闭
      /
      处置
      请求。就为了这个目的

      void R(MemoryStream M)
      {
          using (B = new BinaryWriter(new NonClosingStreamWrapper(M)))
          {
              // write some stuff using B
          }
      
          S(M);  // now pass M to another routine for further processing
      }    
      

      只需将其添加到这里,一个非常简单的解决方案是而不是对编写器进行处理()

      void R(MemoryStream M)
      {
          B = new BinaryWriter(M);
      
          // write some stuff using B        
          B.Flush();
          S(M);  // now pass M to another routine for further processing
      }
      
      现在,您只需担心将B保留在范围内,而在R()期间它将保持在范围内


      这可能不是最好的解决方案,但值得注意的是,读者和作者不需要自行处理。

      值得强调的是:这种方法既适用于封闭流,也适用于活动流。我不知道C#,但在Java中,您只需放弃而不关闭BinaryWriter即可。使用{…}不是构造强制关闭吗?那就不要用那个结构!注意,但您确实需要确保在放弃BinaryWriter之前刷新它。但请确保在完成后调用B.flush(),以防它没有将所有内容传递给M。(这是Java中需要的,不知道C#)好的,Adrian&Marc,我忘了刷新().你就不能避免调用close/Dispose吗?我不明白你为什么说最好使用GetBuffer,然后使用Array.copy进行复制。如果我想要一个副本,我会使用数组。从MSDN文档中,这个方法会从数组中省略MemoryStream中未使用的字节。要获取整个缓冲区,请使用GetBuffer方法。上面的“此方法”指的是MemoryStream.ToArray()-1,用于发布到不允许免费查看其内容的网站,这是非常无用的