处理streamreader会关闭流吗?
-
21-08-2019 - |
题
我将一个流发送到要写入的方法,并且在这些方法中我使用二进制读取器/wrtier。当读取器/写入器被处置时,可以通过 using
或者只是当它没有被引用时,流也关闭吗?
我会发送一个 BinaryReader/Writer,但我也在使用 StreamReader(也许我应该绕过它。我只将其用于 GetLine 和 ReadLine)。如果每次写入器/读取器关闭时它都会关闭流,那么这是非常麻烦的。
解决方案
是的, StreamReader
, StreamWriter
, BinaryReader
和 BinaryWriter
当您调用时,所有都关闭/处置其底层流 Dispose
在他们。他们 不 如果读取器/写入器只是垃圾收集,则处置流 - 您应该始终处置读取器/写入器,最好使用 using
陈述。(事实上,这些类都没有,也不应该有。)
就我个人而言,我更喜欢为流提供一个 using 语句。你可以筑巢 using
不带大括号的语句非常整齐:
using (Stream stream = ...)
using (StreamReader reader = new StreamReader(stream, Encoding.Whatever))
{
}
尽管 using
流的语句有些多余(除非 StreamReader
构造函数抛出异常)我认为这是最佳实践,因为如果你摆脱了 StreamReader
并且稍后直接使用该流,您就已经拥有了正确的处理语义。
其他提示
这是一个旧的,但今天我想做一些类似的事情,发现事情已经改变了。从 .net 4.5 开始,有一个 leaveOpen
争论:
public StreamReader( Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen )
唯一的问题是其他参数的设置并不完全明显。这里有一些帮助:
从 MSDN 页面 对于 StreamReader 构造函数(流):
该构造函数初始化了对UTF8Encoding的编码,使用流参数的底流属性以及内部缓冲区大小为1024字节。
那只剩下 detectEncodingFromByteOrderMarks
由此判断 源代码 是 true
public StreamReader(Stream stream)
: this(stream, true) {
}
public StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks)
: this(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize) {
}
如果公开其中一些默认值或者参数是可选的,这样我们就可以指定我们想要的参数,那就太好了。
是,它的作用。您可以通过查看与反射器实施验证这一点。
protected override void Dispose(bool disposing)
{
try
{
if ((this.Closable && disposing) && (this.stream != null))
{
this.stream.Close();
}
}
finally
{
if (this.Closable && (this.stream != null))
{
this.stream = null;
this.encoding = null;
this.decoder = null;
this.byteBuffer = null;
this.charBuffer = null;
this.charPos = 0;
this.charLen = 0;
base.Dispose(disposing);
}
}
}
六晚年但也许这会帮助别人。
的StreamReader做它被设置时关闭连接。然而,“使用(流流= ...){...}”与的StreamReader / StreamWriter的可以导致流被布置两次:(1)当StreamReader对象被设置(2),并且当流使用块关闭。运行VS代码分析时,这将导致一个CA2202警告。
另一种解决方案,直接从 CA2202 页采取,是使用一个try / finally块。正确设置,这将仅关闭连接一次。
近的 CA2202 ,Microsoft建议底部使用以下:
Stream stream = null;
try
{
stream = new FileStream("file.txt", FileMode.OpenOrCreate);
using (StreamWriter writer = new StreamWriter(stream))
{
stream = null;
// Use the writer object...
}
}
finally
{
if(stream != null)
stream.Dispose();
}
而不是...
// Generates a CA2202 warning
using (Stream stream = new FileStream("file.txt", FileMode.Open))
using (XmlReader reader = new XmlReader (stream))
{
// Use the reader object...
}
是。呼吁和IDisposable接口的Dispose()(其中“使用”一样)应该作出对象清理其所有资源。这包括冲洗和关闭它们的文件描述符流。
如果,你的情况,你想把它传递给其他的方法,那么你需要确保这些方法没有做好自己的读/在使用块的写入。
如果您需要是重写的StreamWriter类处置方法的一个简单方法解决此问题。请参见我的文章在这里就如何做到这一点的代码:
流设置或者通过“使用”关键字或调用dispose明确地