你能让StreamReader不要处理底层流吗?

Joh*_*zen 49 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_doing.log", FileMode.OpenOrCreate, FileAccess.ReadWrite);

using(var sw = new StreamWriter(this.logFile))
{
    // Write additional data out...
}
Run Code Online (Sandbox Code Playgroud)

无需打开文件两次?

我似乎无法使StreamReader不处理我的流.我也不想让它超出范围.然后垃圾收集器最终将调用Dispose,杀死流.

Sim*_*han 70

.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)
Run Code Online (Sandbox Code Playgroud)

  • 这个问题是它迫使我弄清楚要传递什么编码,以使StreamReader的行为与我使用`StreamReader(Stream)`构造函数打开它时的行为相同.所以我仍然使用"不要处置并希望没有我的同事'正确'的方法,通过将StreamReader放入一个使用块"方法:( (20认同)
  • @phoog :(赶上我的收件箱) - MSDN应列出转发式重载的默认值,例如`StreamReader(Stream)`说"这个构造函数将编码初始化为UTF8Encoding,使用stream参数初始化BaseStream属性,以及内部缓冲区大小为1024字节." (18认同)
  • @SimonBuchan但我不应该在我的程序中硬编码这些默认值.应该更改`StreamReader()`构造函数以获取选项样式的类参数,就像`XmlReaderSettings`的工作方式一样.然后可以通过框架管理默认值,并以非ABI中断和非硬件方式添加新参数. (6认同)
  • 使用命名参数可以避免手动指定默认值: new StreamReader(stream, leftOpen: true) (3认同)
  • using(var reader = StreamReader(OtherStream, System.Text.Encoding.UTF8, 1024, true)) { ... } 如果您想坚持使用默认值。*评论已移动* (2认同)
  • StreamReader 的源代码是 https://referencesource.microsoft.com/#mscorlib/system/io/streamreader.cs。您可以对中间参数使用 Microsoft 默认值:Encoding=UTF8、detectedEncodingFromByteOrderMarks=true、bufferSize=4096。然后设置 leaveOpen=true。 (2认同)

Meh*_*ari 47

我也不想让它超出范围.然后垃圾收集器最终将调用Dispose,杀死流.

垃圾收集器将调用Finalize方法(析构函数),而不是Dispose方法.终结器将调用Dispose(false)哪个不会处理底层流.你应该是离开OK StreamReader,如果你需要直接使用底层流超出范围.只需确保在适当的时候手动处理基础流.


Tho*_*que 16

您可以使用NonClosingStreamWrapperJon Skeet的MiscUtil库中的类,它正是为了这个目的