我正在向要写入的方法发送一个流,在这些方法中我使用的是二进制阅读器/ wrtier。当读者/作者被释放时,无论是using
还是仅当它被引用时,流也被关闭了?
我会发送一个BinaryReader / Writer,但我也在使用StreamReader(也许我应该绕过它。我只是将它用于GetLine和ReadLine)。如果每次作家/读者关闭时关闭流都会非常麻烦。
答案 0 :(得分:189)
是的,StreamReader
,StreamWriter
,BinaryReader
和BinaryWriter
在您呼叫Dispose
时关闭/处置其基础流。如果读者/作者只是垃圾收集,他们不处理流 - 你应该总是处理读者/作者,最好用using
语句。 (事实上,这些类都没有终结器,也不应该有终结器。)
我个人更喜欢为流提供一个using语句。您可以非常巧妙地嵌套using
语句而不是括号:
using (Stream stream = ...)
using (StreamReader reader = new StreamReader(stream, Encoding.Whatever))
{
}
即使流的using
语句有点多余(除非StreamReader
构造函数抛出异常),我认为如果你摆脱StreamReader
和只需在以后直接使用流,您就已经拥有了正确的处理语义。
答案 1 :(得分:38)
这是一个旧的,但我想今天做类似的事情,发现事情已经发生了变化。从.net 4.5开始,有一个leaveOpen
参数:
public StreamReader( Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen )
唯一的问题是,为其他参数设置的内容并不完全明显。这是一些帮助:
来自 the msdn page 的StreamReader构造函数(流):
此构造函数将编码初始化为UTF8Encoding,即 BaseStream属性使用stream参数和内部 缓冲区大小为1024字节。
刚刚离开detectEncodingFromByteOrderMarks
the source code 判断true
public StreamReader(Stream stream)
: this(stream, true) {
}
public StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks)
: this(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize) {
}
如果暴露了其中一些默认值或者参数是可选的,那么我们可以只指定我们想要的那些默认值。
答案 2 :(得分:27)
是的,确实如此。您可以通过使用Reflector查看实现来验证这一点。
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);
}
}
}
答案 3 :(得分:10)
迟到六年但也许这可能对某人有所帮助。
StreamReader在处理时会关闭连接。但是,"使用(Stream stream = ...){...}"使用StreamReader / StreamWriter可以导致Stream被处理两次:(1)当StreamReader对象被释放时(2)以及Stream using block关闭时。运行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...
}
答案 4 :(得分:2)
是。调用Dispose()和IDisposable(“使用”)应该使对象清理其所有资源。这包括刷新和关闭文件描述符的流。
如果您希望将其传递给其他方法,那么您需要确保这些方法不会在使用块中进行读/写。
答案 5 :(得分:1)
如果需要,一种简单的方法是重写StreamWriter类Dispose方法。请参阅我的帖子,了解有关如何操作的代码:
答案 6 :(得分:-3)
通过“使用”关键字或明确调用dispose来处理流