关闭 FileStream 会关闭 StreamReader 吗?
如果我使用 FileStream 创建 StreamReader,当我关闭 FileStream 时 StreamReader 会关闭还是我也需要关闭 StreamReader?
public void ReadFile()
{
var file = new FileStream("c:\file.txt", FileMode.Open, FileAccess.Read);
var reader = new StreamReader(file);
try
{
txtFile.Text = reader.ReadToEnd();
}
catch (Exception)
{
throw;
}
finally
{
file.Close();
}
}
If I use a FileStream to create a StreamReader, will the StreamReader close when I close the FileStream or will I need to close the StreamReader too?
public void ReadFile()
{
var file = new FileStream("c:\file.txt", FileMode.Open, FileAccess.Read);
var reader = new StreamReader(file);
try
{
txtFile.Text = reader.ReadToEnd();
}
catch (Exception)
{
throw;
}
finally
{
file.Close();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
基本上是的。您实际上不必关闭 StreamReader。如果这样做,它所做的只是关闭底层流。
@Bruno 关于关闭最外层包装器提出了一个很好的观点。最好关闭最外层流并让它关闭底层流,以确保正确释放所有资源。
从反光镜...
Essentially yes. You don't actually have to close a StreamReader. If you do, all it does is closes the underlying stream.
@Bruno makes a good point about closing the outer-most wrapper. It is good practice to close the outer-most stream and let it close underlying streams in order to ensure all resources are released properly.
From Reflector...
不可以。您应该关闭
阅读器
。实际上,这可能不会出现任何问题,但是 StreamReader 可能会增加一些可能需要清理的开销。所以你应该总是关闭最上面的包装。No. You should close the
reader
instead. In practice, this might not present any problem but, theStreamReader
could add some overhead that might need to be cleaned. So you should always close the top most wrapper.您也可以只使用 File.ReadAllText 方法:
You could also just use the File.ReadAllText method:
您不需要关闭 StreamReader,因为它不拥有任何非托管资源。关闭 FileStream 就足够了。您可以使用
using
重写您的代码,如下所示:一般来说,如果您有疑问,最好确保安全,并在使用完所有 IDisposable 对象后释放它们。
You don't need to close the StreamReader because it doesn't own any unmanaged resources. Closing the FileStream is sufficient. You can rewrite your code with
using
like this:In general if you are in doubt it is best to be safe and Dispose all IDisposable objects when you have finished using them.
不。最好的办法是按照打开它们的相反顺序关闭它们。
No. The best thing to do is close them in reverse order that you opened them.
在我看来,总体上做到这一点的最佳方法是让 FileStream 仅关闭其自身。它并不隐式地了解其自身之上的层中存在的任何内容,因此它执行任何会影响这些更高层的操作实际上都是错误的。
话虽如此,更高级别的构造也不应该公理地假设任何有关任何提供的底层的任何内容,或者如果他们这样做,他们应该明确地这样做:
1)如果它是从现有流创建的,则更高级别的构造构造应该能够独立关闭底层流(实际上只是处理它分配给自己使用的任何资源),或者关闭包括底层流。这些应该是两个不同的函数调用,例如 Close() 和 CloseSelf() (如果要以向后兼容现有代码的方式实现)。
2)如果它不是从现有流创建的(也就是说,构造函数必须创建底层流),那么关闭更高级别的构造也应该强制底层流关闭,因为在这种情况下底层流是高层结构的隐含部分。在这种情况下,CloseSelf() 将简单地调用 Close()。
以这种方式实现这些类似乎很浪费。如果您计划使用相同的文件(例如)串行输入和串行输出,并且您希望获得对后代类的更高级别功能的访问权限,系统实际上会强制您将其视为两个不同的实体。您的替代方案是坚持较低级别的构造并自己实现较高级别的功能 - 有效地重新实现您自己的已存在的后代类的特殊版本。
如果按照上述方式完成,典型的功能将像现在一样简单地实现,但对于更复杂的应用程序,人们将保留在文件上放置单个锁并在需要时根据需要重新调整其用途的能力,如下所示:与必须放弃锁和所有相关资源然后立即重新分配它们相反 - 在没有任何正当理由的情况下增加系统开销和内存碎片。
但在现有条件下,正确的做法是显而易见的。不能假设 FileStream 了解有关它所属的任何对象的任何信息,因此您必须关闭最外层的封闭构造。正如布鲁诺等人所指出的,无论它是否以任何方式工作,这都适用,并且出于他们给出的原因 - 兼容性。假设是最丑陋的 bug 的曾祖父。
It seems to me that the best way to do this overall would be to have the FileStream closing only itself. It does not implicitly have knowledge of anything that exists in a layer above itself, so it is effectively an error for it to do anything that would affect those higher layers.
Having said that, the higher-level constructs should not axiomatically assume anything about any supplied underlying layer as well, or if they do so, they should do so explicitly:
1) If it was created from an existing stream, then the higher-level construct should be able to be closed INDEPENDENTLY of the underlying stream (effectively just disposing of any resources it allocated for its own use), or closed INCLUDING the underlying stream. These should be two distinct function calls, for example Close() and CloseSelf() (if this were to be implemented in such a way as to be backward compatible with existing code).
2) If it was not created from an existing stream (that is, the constructor had to create the underlying stream), then closing the higher-level construct should force the underlying stream to close as well, since in that case the underlying stream is an implicit part of the higher-level construct. In this case, CloseSelf() would simply call Close().
It seems wasteful to implement these classes the way it was done. If you plan to use the same file for (as an example) serial input and serial output, you are effectively forced by the system to treat it as two distinct entities if you wish to gain access to the higher level functionality of the descendant classes. Your alternative is to stick to the lower level construct and implement the higher-level functionality yourself - effectively re-implementing your own special versions of descendant classes that already exist.
If it were done as described above, the typical functionality would be as simple to implement as it is now, but for more sophisticated applications one would retain the ability to place a single lock on a file and re-purpose it as required when required as opposed to having to relinquish the lock and all associated resources and then instantly reallocate them all over again - adding overhead and memory fragmentation to the system without any valid reason.
Under the existing conditions, though, the correct thing is clear. The FileStream cannot be assumed to know anything about any object it becomes a part of, so you must close the outermost enclosing construct. This applies regardless of whether or not it works either way, as Bruno et al have noted, and for the reason they gave - compatibility. Assumption is the great-granddaddy of the ugliest bugs.
有趣的是,关闭 StreamReader 或 writer 会影响所属 FileStream 的读/写状态。这似乎意味着您不能使用 StreamReader,然后使用相同的文件流使用 StreamWriter。
An interesting aside is that closing a StreamReader or writer will affect the read/write status of the owning FileStream. This seems to mean that you cannot use a StreamReader and then a StreamWriter using the same filestream.