C# 您能否阻止StreamReader处理底层流?
有没有办法做到这一点:C# 您能否阻止StreamReader处理底层流?,c#,file-io,C#,File Io,有没有办法做到这一点: this.logFile = File.Open("what_r_u_doing.log", FileMode.OpenOrCreate, FileAccess.ReadWrite); using(var sr = new StreamReader(this.logFile)) { // Read the data in } // ... later on in the class ... this.logFile = File.Open("what_r_u
this.logFile = File.Open("what_r_u_doing.log", FileMode.OpenOrCreate, FileAccess.ReadWrite);
using(var sr = new StreamReader(this.logFile))
{
// Read the data in
}
// ... later on in the class ...
this.logFile = File.Open("what_r_u_doing.log", FileMode.OpenOrCreate, FileAccess.ReadWrite);
using(var sw = new StreamWriter(this.logFile))
{
// Write additional data out...
}
不必打开文件两次
我似乎无法让StreamReader不处理我的流。我也不想让它超出范围。然后,垃圾收集器最终将调用Dispose,终止流。完成后,请自己在
try
/finally
子句中关闭它
var sr = new StreamReader();
try {
//...code that uses sr
//....etc
}
finally
{
sr.Close();
}
只需移除使用块。我认为,如果不想对流执行Dispose()操作,则不必对StreamReader执行Dispose() 我也不想让它超出范围。然后垃圾收集器将最终调用Dispose,终止流
垃圾收集器将调用
Finalize
方法(析构函数),而不是Dispose
方法。终结器将调用Dispose(false)
,这将不处理底层流。如果需要直接使用底层流,则可以将StreamReader
退出范围。只要确保在适当的时候手动处理底层流。您可以使用Jon Skeet的非关闭流说话者
类,它正是为了这个目的您可以创建一个从StreamReader继承的新类,并覆盖Close方法;在Close方法中,调用Dispose(false),正如Mehrdad指出的那样,它不会关闭流。当然,StreamWriter也是如此
但是,似乎更好的解决方案是,只要您需要,就保留StreamReader和StreamWriter实例。如果您已经计划让流保持打开状态,那么还可以让StreamReader和StreamWriter保持打开状态。如果正确使用StreamWriter.Flush和Stream.Seek,则即使在执行读写操作时,也应该能够执行此操作。.NET 4.5最终将通过StreamReader和StreamWriter上采用leaveOpen参数的新构造函数解决此问题:
StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen)
StreamWriter(Stream stream, System.Text.Encoding encoding, int bufferSize, bool leaveOpen)
使用另一个构造函数重载,您可以在其中将“leveopen”参数指定为“true”我总是使用这样的方法: (它还使用
leaveOpen
参数)
用法:
using (var reader = file.WrapInNonClosingStreamReader())
{
....
}
我可以使用
leaveOpen
参数,而无需指定所有构造函数参数(编码或缓冲区大小),如下所示:
using var streaReader = new StreamReader(stream, leaveOpen: true);
问题是,它迫使我弄清楚要传递什么编码,以使StreamReader的行为与我使用
StreamReader(Stream)
构造函数打开它时的行为相同。因此,我仍然在使用“不要处理并希望我的同事没有人通过将StreamReader放入使用块来‘纠正’该方法”的方法:(@phoog:(在我的收件箱中)MSDN应该列出转发样式重载的默认值,例如StreamReader(Stream)
说“此构造函数将编码初始化为UTF8Encoding,使用stream参数将BaseStream属性初始化为1024字节。”@SimonBuchan但我不必在程序中硬编码这些默认值。StreamReader()
构造函数应该被修改为采用选项样式的类参数,比如XmlReaderSettings
的工作方式。然后可以由框架管理默认值,并以非ABI中断和非硬烘焙的方式添加新参数。使用(var reader=StreamReader(OtherStream,System.Text.Encoding.UTF8,1024,true)){…}如果您想坚持默认值。comment Moved StreamReader的源代码是。您可以使用Microsoft默认值作为中间参数:Encoding=UTF8,detectedEncodingFromByteOrderMarks=true,bufferSize=4096。然后设置leaveOpen=true。但是将来是否有可能修改StreamReadero保留一些非管理的资源,开始实现终结器,然后当超出范围时,在垃圾收集器终结流时随机关闭流?或者我们应该假设,既然现在不发生这种情况,它永远不会发生?根据引用源,这似乎是一个好的答案。这相当于调用流无参数构造函数,但将leaveOpen指定为true。“没有给定与所需的形式参数“encoding”相对应的参数。(.NET 4.8)
using var streaReader = new StreamReader(stream, leaveOpen: true);