为什么部署StreamReader会使流不可读? [英] Why disposing StreamReader makes a stream unreadable?

查看:449
本文介绍了为什么部署StreamReader会使流不可读?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从头到尾读取两次流.

I need to read a stream two times, from start to end.

但是下面的代码引发ObjectDisposedException: Cannot access a closed file异常.

But the following code throws an ObjectDisposedException: Cannot access a closed file exception.

string fileToReadPath = @"<path here>";
using (FileStream fs = new FileStream(fileToReadPath, FileMode.Open))
{
    using (StreamReader reader = new StreamReader(fs))
    {
        string text = reader.ReadToEnd();
        Console.WriteLine(text);
    }

    fs.Seek(0, SeekOrigin.Begin); // ObjectDisposedException thrown.

    using (StreamReader reader = new StreamReader(fs))
    {
        string text = reader.ReadToEnd();
        Console.WriteLine(text);
    }
}

为什么会这样?真正处置了什么?以及为什么操纵StreamReader会以这种方式影响关联的流?期望可搜索的流可以被读取多次,包括被多个StreamReader读取,是否合乎逻辑?

Why is it happening? What is really disposed? And why manipulating StreamReader affects the associated stream in this way? Isn't it logical to expect that a seekable stream can be read several times, including by several StreamReaders?

推荐答案

之所以会发生这种情况,是因为StreamReader接管了流的所有权".换句话说,它使自己负责关闭源流.一旦程序调用DisposeClose(在您的情况下保留using语句作用域),它也将处理源流.在您的情况下调用fs.Dispose().因此,文件流在离开第一个using块之后就消失了.这是一致的行为,.NET中包装另一个流的所有流类都以这种方式运行.

This happens because the StreamReader takes over 'ownership' of the stream. In other words, it makes itself responsible for closing the source stream. As soon as your program calls Dispose or Close (leaving the using statement scope in your case) then it will dispose the source stream as well. Calling fs.Dispose() in your case. So the file stream is dead after leaving the first using block. It is consistent behavior, all stream classes in .NET that wrap another stream behave this way.

StreamReader有一个构造函数,可以说它拥有源流.但是,无法从.NET程序访问它,该构造函数是内部的.

There is one constructor for StreamReader that allows saying that it doesn't own the source stream. It is however not accessible from a .NET program, the constructor is internal.

在这种特定情况下,您可以通过不对StreamReader使用using语句来解决此问题.但是,这是一个相当麻烦的实现细节.当然,您可以找到更好的解决方案,但是代码太过复杂,无法提出真正的解决方案.

In this particular case, you'd solve the problem by not using the using-statement for the StreamReader. That's however a fairly hairy implementation detail. There's surely a better solution available to you but the code is too synthetic to propose a real one.

这篇关于为什么部署StreamReader会使流不可读?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆