简体   繁体   English

是不是可以不关闭StreamReader / StreamWriter来保持底层流打开?

[英]Is it okay to not close StreamReader/StreamWriter to keep the underlying stream open?

I have a class that essentially wraps a Stream for reading/writing, but that stream is expected to be managed by the consumer of that class. 我有一个基本上包装Stream用于读/写的类,但该流预计由该类的使用者管理。 For ease of use, I use StreamReader and StreamWriter classes to perform I/O operations on the stream. 为了便于使用,我使用StreamReader和StreamWriter类在流上执行I / O操作。 Normally I'd wrap the reader and writer in using blocks, but I want to avoid closing the reader and writer because doing so also closes the underlying stream and I have to keep it open. 通常我会将读取器和写入器包装在using块中,但我想避免关闭读取器和写入器,因为这样做也会关闭底层流,我必须保持打开状态。

Is it safe in terms of memory/resource management to not close a StreamReader/StreamWriter if I expect the underlying Stream to be managed by the caller? 如果我希望调用者管理基础Stream,那么在内存/资源管理方面是否安全不关闭StreamReader / StreamWriter? Will the reader and writer be garbage collected when the stream is explicitly closed elsewhere? 当流在其他地方明确关闭时,读写器是否会被垃圾收集?

public class Wrapper 
{
    private Stream _underlyingStream;
    public Wrapper(Stream underlyingStream) 
    {
        _underlyingStream = underlyingStream;
    }

    public string GetValue() 
    {
        _underlyingStream.Seek(0, SeekOrigin.Begin);
        var reader = new StreamReader(_underlyingStream);
        return reader.ReadToEnd(); // we're done, but the stream is not ours to close
    }
}

If nobody closes the streams then ultimately the finalizer will be called which should call dispose and close them upon GC. 如果没有人关闭流,那么最终将调用终结器,它应该调用dispose并在GC上关闭它们。 But that's quite a crap-shoot resource-wise because it leaves whatever possibly-expensive resources allocated until GC. 但这在资源方面相当不错,因为它会留下任何可能昂贵的资源,直到GC。 It could get worse the longer your object lives, especially if it survives collections to be promoted to gen 1 or even 2. 你的物体存在的时间越长,情况就会越糟,特别是如果它能够保存到第1代甚至2代的藏品中。

It sure would be nice if you could present something to your caller that isolates this. 如果你能向你的呼叫者提供一些可以隔离它的东西,那肯定会很好。 Perhaps you can cache something from the stream so you can close it while still serving the content to your caller? 也许你可以从流中缓存一些东西,这样你就可以在向你的调用者提供内容的同时关闭它?

EDIT after your edit: Now that I see your caller PASSES you a stream to operate on, my answer has to be different! 编辑后编辑:现在我看到你的来电者通过了你的流来操作,我的答案必须与众不同! It's very clear that your caller should be managing the stream's lifetime. 很明显,您的调用者应该管理流的生命周期。 I had the impression at first that your class created a stream and hoped the caller managed it. 我最初的印象是,你的班级创建了一个流,并希望调用者管理它。

The easiest way to solve this is to wrap the stream in your own class that derives from System.IO.Stream 解决此问题的最简单方法是将流包装在您自己的类中,该类派生自System.IO.Stream

Example: http://csharptest.net/browse/src/Library/IO/NonClosingStream.cs 示例: http//csharptest.net/browse/src/Library/IO/NonClosingStream.cs

It is definetelly not ok. 这是不正确的。 read this from msdn 从msdn读取

The close calls the Dispose method passing a true value. close调用Dispose方法传递一个true值。 Flushing the stream will not flush its underlying encoder unless you explicitly call Close. 除非您明确调用Close,否则刷新流不会刷新其底层编码器。

Try to encapsulate all IO in a class. 尝试将所有IO封装在一个类中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM