代码之家  ›  专栏  ›  技术社区  ›  JasonRShaver

dos stream.dispose始终调用stream.close(和stream.flush)

  •  61
  • JasonRShaver  · 技术社区  · 16 年前

    如果我有以下情况:

    StreamWriter MySW = null;
    try
    {
       Stream MyStream = new FileStream("asdf.txt");
       MySW = new StreamWriter(MyStream);
       MySW.Write("blah");
    }
    finally
    {
       if (MySW != null)
       {
          MySW.Flush();
          MySW.Close();
          MySW.Dispose();
       }
    }
    

    我能打个电话吗? MySW.Dispose() 即使提供了关闭,也跳过关闭?是否有任何流内建无法按预期工作(如cryptostream)?

    如果不是,那么下面是错误代码:

    using (StreamWriter MySW = new StreamWriter(MyStream))
    {
       MySW.Write("Blah");
    }
    
    8 回复  |  直到 9 年前
        1
  •  80
  •   Community CDub    8 年前

    我可以直接调用mysw.dispose()和 跳过关闭操作,即使它是 提供?

    是的,这就是它的目的。

    有流实现吗 不按预期工作(比如 密码流?

    假设一个对象实现 IDisposable 它会妥善处理自己。

    如果它没有,那就是一个bug。

    如果不是,那么下面是不是很糟糕 代码:

    不,该代码是处理实现的对象的推荐方法 不可分的 .

    更优秀的信息在公认的答案中 Close and Dispose - which to call?

        2
  •  58
  •   Andrew Hare    16 年前

    我用反光镜发现 System.IO.Stream.Dispose 如下所示:

    public void Dispose()
    {
        this.Close();
    }
    
        3
  •  21
  •   ScottS    16 年前

    正如丹尼尔·布鲁克纳所说,处置和关闭实际上是一回事。

    但是,流在释放/关闭时不调用flush()。filestream(我假设任何其他具有缓存机制的流)在释放时都会调用flush()。

    如果要扩展流或memoryStream等,则在必要时释放/关闭时需要实现对flush()的调用。

        4
  •  3
  •   Tamas Czinege    16 年前

    streamwriter.dispose()和stream.dispose()都释放了对象持有的所有资源。它们都关闭了底层流。

    stream.dispose()的源代码(请注意,这是实现细节,因此不要依赖它):

    public void Dispose()
    {
        this.Close();
    }
    

    streamwriter.dispose()(与stream.dispose()相同):

    protected override void Dispose(bool disposing)
    {
        try
        {
            // Not relevant things
        }
        finally
        {
            if (this.Closable && (this.stream != null))
            {
                try
                {
                    if (disposing)
                    {
                        this.stream.Close();
                    }
                }
                finally
                {
                    // Not relevant things
                }
            }
        }
    }
    

    不过,我通常在处理流/流作者之前隐式地关闭它们-我认为它看起来更干净。

        5
  •  3
  •   to StackOverflow    16 年前

    当关闭/释放时,所有标准流(filestream、cryptostream)都将尝试刷新。我认为对于任何Microsoft流实现,您都可以依赖于此。

    因此,如果刷新失败,close/dispose可能会引发异常。

    事实上,iirc在.NET 1.0的filestream实现中存在一个错误,因为如果刷新引发异常,它将无法释放文件句柄。通过向Dispose(Boolean)方法添加Try/Finally块,在.NET 1.1中修复了此问题。

        6
  •  3
  •   clemahieu    16 年前

    对于需要手动关闭的对象,应尽一切努力在using块中创建该对象。

    //Cannot access 'stream'
    using (FileStream stream = File.Open ("c:\\test.bin"))
    {
       //Do work on 'stream'
    } // 'stream' is closed and disposed of even if there is an exception escaping this block
    // Cannot access 'stream' 
    

    这样,就永远不会从using子句的上下文中错误地访问'stream',并且文件总是关闭的。

        7
  •  3
  •   Steve Sheldon    13 年前

    我在.NET源代码中查找了stream类,它包含以下内容,建议您可以…

        // Stream used to require that all cleanup logic went into Close(),
        // which was thought up before we invented IDisposable.  However, we 
        // need to follow the IDisposable pattern so that users can write
        // sensible subclasses without needing to inspect all their base
        // classes, and without worrying about version brittleness, from a
        // base class switching to the Dispose pattern.  We're moving 
        // Stream to the Dispose(bool) pattern - that's where all subclasses
        // should put their cleanup starting in V2. 
        public virtual void Close() 
        {
            Dispose(true); 
            GC.SuppressFinalize(this);
        }
    
        public void Dispose() 
        {
            Close(); 
        } 
    
        8
  •  2
  •   Daniel Brückner    16 年前

    Stream.Close 通过调用实现 Stream.Dispose 反之亦然——所以这些方法是等效的。 流关闭 存在只是因为关闭流听起来比处理流更自然。

    此外,您应该尽量避免显式调用此方法,并使用 using 语句,以便免费获得正确的异常处理。