我正在尝试实现FileSystemWatcher
。但是,从来没有调用过我的OnChange事件处理程序。观察者应该监视进程中另一个线程正在更新的日志文件。使用new StreamWriter(File.Open("C:\\temp\\myLog.txt", FileMode.Create, FileAccess.Write, FileShare.Read));
打开文件吗?
public MyFormConstructor()
{
InitializeComponent();
this._fileSystemWatcher = new FileSystemWatcher();
this._fileSystemWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.Size;
this._fileSystemWatcher.Path = "C:\\temp\\";
this._fileSystemWatcher.Filter = "myLog.txt";
this._fileSystemWatcher.Changed += this.OnLogChanged;
this._fileSystemWatcher.Created += this.OnLogChanged;
this._fileSystemWatcher.Deleted += this.OnLogChanged;
this._fileSystemWatcher.Renamed += this.OnLogChanged;
this._fileSystemWatcher.EnableRaisingEvents = true;
}
private void OnLogChanged(object source, FileSystemEventArgs e)
{
switch (e.ChangeType) // <-- never gets here
{
case WatcherChangeTypes.Changed:
this.UpdateLogView();
break;
case WatcherChangeTypes.Created:
case WatcherChangeTypes.Deleted:
case WatcherChangeTypes.Renamed:
default:
throw new NotImplementedException();
}
}
我在处理StreamWriter时收到文件系统事件,但没有。
因此处置。有关无法上班的想法,请参阅附录A。
public class FlushingTextTraceListener : TextWriterTraceListener
{
public FlushingTextTraceListener(string filePath)
{
FilePath = filePath;
}
public String FilePath { get; set; }
public override void Write(string message)
{
using (var sw = new StreamWriter(File.Open(FilePath, FileMode.Create,
FileAccess.Write, FileShare.Read)))
{
sw.Write(message);
}
}
public override void WriteLine(string message)
{
using (var sw = new StreamWriter(File.Open(FilePath, FileMode.Create,
FileAccess.Write, FileShare.Read)))
{
sw.WriteLine(message);
}
}
}
用法:
_dbgTraceListener = new FlushingTextTraceListener("C:\\temp\\myLog.txt");
Debug.Listeners.Add(_dbgTraceListener);
我尝试过的其他方法,由于我可能已经搞砸了其中一个或全部,所以进行了详细说明。为了进行测试,我在WPF窗口上放置了一个按钮,并在该按钮的click方法中跟踪了一行文本:
Trace.WriteLine(DateTime.Now);
在该事件处理程序中,在该行之后,我尝试了一些其他操作。当然,您不是在寻找围绕Trace.WriteLine()的包装方法,但是我发现如果其中一种方法可以正常使用它,那将是一种方法。
这些没有引起文件系统事件,但是它们没有引发异常:
Trace.Flush();
_dbgTraceListener.Flush();
_dbgOutputWriter.Flush();
我尝试通过两种方式通过设置上次访问时间来“触摸”文件,但出现了异常(System.IO.IOException:'该进程无法访问文件'C:\ temp \ myLog.txt',因为它正在由另一个进程使用。')
new FileInfo("C:\\temp\\myLog.txt").LastWriteTime = DateTime.UtcNow;
File.SetLastWriteTimeUtc("C:\\temp\\myLog.txt", DateTime.UtcNow);
[我在cmd.exe中键入type c:\temp\myLog.txt
时发现访问事件,因此我尝试在C#中以只读方式打开文件并立即将其处理:
using (var f = File.Open("C:\\temp\\myLog.txt", FileMode.Open, FileAccess.Read, FileShare.Read))
;
和
using (var f = File.OpenRead("C:\\temp\\myLog.txt"))
;
在两种情况下,我都有与上述相同的例外。对于此测试,我使用FileShare.ReadWrite
标志创建了_dbgOutputWriter,如下所示:
_dbgOutputWriter = new StreamWriter(File.Open("C:\\temp\\myLog.txt", FileMode.Create,
FileAccess.Write, FileShare.ReadWrite));
允许随后打开文件进行读取或写入。如果未指定此标志,则打开文件以进行读取或写入的任何请求(通过此过程或其他过程)都将失败,直到关闭文件为止。但是,即使指定了此标志,可能仍需要访问文件的附加权限。
强调我的。也许这只是意味着用户必须有权访问文件。