c#StreamWriter处理-返回基础内存流(打开)

c#StreamWriter处理-返回基础内存流(打开),c#,C#,除了这里的注释(),我还没有找到一个很好的答案来回答我关于让StreamWriter保持打开状态的担忧。我想返回由StreamWriter以安全、干净的方式编写的MemoryStream(open) 让我举一个相当简单的例子。 我想像这样使用方法GetMemoryStream(): String[] content = { "large", "string", "array", "test" }; MemoryStream ms = GetMemoryStream

除了这里的注释(),我还没有找到一个很好的答案来回答我关于让StreamWriter保持打开状态的担忧。我想返回由StreamWriter以安全、干净的方式编写的MemoryStream(open)

让我举一个相当简单的例子。 我想像这样使用方法GetMemoryStream()

        String[] content = { "large", "string", "array", "test" };
        MemoryStream ms = GetMemoryStream(content);
        //byte[] array = ms.ToArray(); //still works after stream is closed but I want an open and working stream.
        using (FileStream fs = new FileStream(@"C:\Test.txt", FileMode.Create, FileAccess.ReadWrite))
        {
            //fs.Write(array, 0, array.Length); 
            ms.WriteTo(fs);
        }
        ms.Dispose();
现在我找到了两种方法:

  • 复制内存流

    public static MemoryStream GetMemoryStream(String[] content)
    {
        MemoryStream result = new MemoryStream();
        using (MemoryStream ms = new MemoryStream())
        using (StreamWriter sw = new StreamWriter(ms))
        {
            foreach (String s in content)
                sw.WriteLine(s);
            sw.Flush();
            ms.CopyTo(result);
        }
        return result;
    }
    
  • 对我来说,这是一个解决办法。似乎(如果我错了,请纠正我)需要两倍的内存和更多的时间。然后我读到了下一篇文章:

  • 让StreamWriter保持打开状态(>=.Net 4.5)

  • 但我对这一说法感到担忧:

    当我离开范围时,StreamWriter会发生什么情况?
    数据是否仍由该StreamWriter对象引用/保存?
    它会被垃圾收集吗?也许在我开始使用MemoryStream之前 调用范围?
    它是否仍然“连接”到MemoryStream,并且可能在我处理ms时被处理

    总而言之:第二个问题会引起麻烦吗


    提前感谢

    使用范围是try-finally块的语法糖,等于下面的代码,Dispose方法被隐式调用

    StreamWriter sw;
    try
    {
        StreamWriter sw = new StreamWriter(ms, Encoding.Default, 1024, true);
        foreach (String s in content)
            sw.WriteLine(s);
    }
    finally
    {
        if(sw != null)
            sw.Dispose();
    }
    

    因此,在阅读了我的问题的评论后,使用以下方法是安全的:

    String[] content = { "large", "string", "array", "test" };
    MemoryStream ms = GetMemoryStream(content);
    using (FileStream fs = new FileStream(@"C:\Test.txt", FileMode.Create, FileAccess.ReadWrite))
    {
       ms.WriteTo(fs);
    }
    ms.Dispose();
    
    --

    我担心StreamWriter会有“剩余”(引用、阻塞内存等)是错误的。StreamWriter可以完全释放,但在使用该ctor时,它不会接触/释放底层MemoryStream。(当我仍然错的时候,请纠正我。)


    多亏了all

    ,您在第二种方法中正确地使用了
    。当您正确地使用
    时,您不应该担心这些事情。这就是为什么
    首先要使用
    的原因。通过链接深入了解处理。@HansPassant-“处理StreamWriter也会处理MemoryStream”-当他们已经将
    true
    作为
    leaveOpen
    参数传递给
    StreamWriter
    构造函数时?第二段代码是正确的,因为
    leaveOpen
    参数为
    true
    ,所以它将使底层流不被显示。感谢您的快速回复@汉斯·帕桑,我已经在使用让记忆流保持打开状态的构造函数了。但我希望在处理返回的MemoryStream后关闭它。不过不要太早。。。我担心StreamWriter会在使用/处理MemoryStream之前收集垃圾。这是真的,但与我的问题(可能格式不好/不精确)不太匹配。当你“嵌套”流时,内部流不知道哪些流被环绕是正常的(如这里所示)。
    StreamWriter
    引用了您在构造函数中传递的
    Stream
    (甚至不知道它是什么类型的流)。没有其他方向的参考资料。是的,谢谢。我想首先困扰我疲惫的大脑的是,StreamWriter的处理也关闭了潜在的流。我认为它们在某种程度上是“绑定”在一起的,但是StreamWriter类的设计很“糟糕”,不是吗?在很多情况下(主要是内存流以外的流),这样做是正确的;所以我不认为这是一个坏的违约,至少它是可以改变的。只要有可能阻止收盘,我同意。但这在以前是不可能的。(您可以继承StreamWriter以防止出现这种情况,但如果无法做到这一点,我将返回到我的第一个aproach)无论哪种方式,谢谢您的输入。=)
    String[] content = { "large", "string", "array", "test" };
    MemoryStream ms = GetMemoryStream(content);
    using (FileStream fs = new FileStream(@"C:\Test.txt", FileMode.Create, FileAccess.ReadWrite))
    {
       ms.WriteTo(fs);
    }
    ms.Dispose();
    
    public static MemoryStream GetMemoryStream(String[] content)
    {
        MemoryStream ms = new MemoryStream();
        using (StreamWriter sw = new StreamWriter(ms, Encoding.Default, 1024, true))
        {
            foreach (String s in content)
                sw.WriteLine(s);
        }
        return ms;
    }