有没有办法做到这一点:
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,杀死流。
答案 0 :(得分:67)
.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)
答案 1 :(得分:46)
我也不想让它超出范围。然后垃圾收集器最终将调用Dispose,杀死流。
垃圾收集器将调用Finalize
方法(析构函数),而不是Dispose
方法。终结器将调用Dispose(false)
,不处理基础流。如果您需要直接使用基础流,那么您应该将StreamReader
超出范围。只需确保在适当的时候手动处理基础流。
答案 2 :(得分:15)
您可以使用Jon Skeet MiscUtil library中的NonClosingStreamWrapper
课程,它正是为了这个目的而提供的
答案 3 :(得分:3)
您可以创建一个继承自StreamReader并覆盖Close方法的新类;在Close方法中,调用Dispose(false),就像Mehrdad指出的那样,不会关闭流。当然,同样适用于StreamWriter。
但是,只要您需要它们,似乎更好的解决方案就是保留StreamReader和StreamWriter实例。如果您已经计划保持流打开,那么您也可以打开StreamReader和StreamWriter。如果你正确使用StreamWriter.Flush和Stream.Seek,你应该能够在读写时都能使这个工作。
答案 4 :(得分:2)
只需删除using-Block。如果您不想对流进行Dispose(),则不必使用Dispose()StreamReader。
答案 5 :(得分:2)
使用另一个构造函数重载,您可以在其中指定" leaveOpen"参数to" true"
答案 6 :(得分:0)
完成后,请在try
/ finally
子句中自行关闭。
var sr = new StreamReader();
try {
//...code that uses sr
//....etc
}
finally
{
sr.Close();
}
答案 7 :(得分:0)
我总是使用这样的东西:
(它还使用leaveOpen
参数)
public static class StreamreaderExtensions
{
public static StreamReader WrapInNonClosingStreamReader(this Stream file) => new StreamReader(file, Encoding.UTF8, true, 1024, true);
}
用法:
using (var reader = file.WrapInNonClosingStreamReader())
{
....
}
答案 8 :(得分:0)
我能够使用leaveOpen
参数而无需指定所有构造函数参数(编码或缓冲区大小),如下所示:
using var streaReader = new StreamReader(stream, leaveOpen: true);