【发布时间】:2019-01-18 11:34:17
【问题描述】:
我正在尝试创建一个简单的日志记录工具来监控文件更改。我使用 FileSystemWatcher 来检测文件的更改,但我发现事件仅在文件关闭时触发,而不是在刷新缓冲区时触发。这意味着如果在文件关闭之前添加了多行,我只会在文件关闭时看到。
这是我的测试示例。
[TestClass]
public class FileWriteTests
{
[TestMethod]
public void TestMethodAfterClose()
{
var currentDir = Environment.CurrentDirectory;
var fileToMonitor = "test.txt";
List<string> output = new List<string>();
var watcherTest = new FileWatcherTest(fileToMonitor, currentDir, output);
File.Delete(Path.Combine(currentDir, fileToMonitor));
using (var writer = new StreamWriter(Path.Combine(currentDir, fileToMonitor), true))
{
writer.WriteLine($"test");
writer.Flush();
}
System.Threading.Thread.Sleep(10);
Assert.AreEqual(1, output.Count);
Assert.AreEqual("test", output[0]);
}
[TestMethod]
public void TestMethodAfterFlush()
{
var currentDir = Environment.CurrentDirectory;
var fileToMonitor = "test.txt";
List<string> output = new List<string>();
var watcherTest = new FileWatcherTest(fileToMonitor, currentDir, output);
File.Delete(Path.Combine(currentDir, fileToMonitor));
using (var writer = new StreamWriter(Path.Combine(currentDir, fileToMonitor), true))
{
try
{
writer.WriteLine($"test");
writer.Flush();
System.Threading.Thread.Sleep(1000);
// add break point here for BareTail
Assert.AreEqual(1, output.Count);
Assert.AreEqual("test", output[0]);
}
catch
{
Assert.Fail("Test failed");
}
}
}
public class FileWatcherTest
{
public string FileName { get; set; }
public string Directory { get; set; }
private List<string> linesRead;
private FileSystemWatcher watcher;
public FileWatcherTest(string fileName, string directory, List<string> output)
{
FileName = fileName;
Directory = directory;
linesRead = output;
watcher = new FileSystemWatcher();
watcher.Path = directory;
watcher.Filter = FileName;
watcher.Changed += Watcher_Changed;
watcher.EnableRaisingEvents = true;
watcher.NotifyFilter = NotifyFilters.Attributes |
NotifyFilters.CreationTime |
NotifyFilters.DirectoryName |
NotifyFilters.FileName |
NotifyFilters.LastAccess |
NotifyFilters.LastWrite |
NotifyFilters.Security |
NotifyFilters.Size;
}
private void Watcher_Changed(object sender, FileSystemEventArgs e)
{
using (var fileStream = File.Open(Path.Combine(Directory, FileName), FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete | FileShare.Inheritable))
{
using (var reader = new StreamReader(fileStream))
{
string line;
while ((line = reader.ReadLine()) != null)
{
linesRead.Add(line);
}
}
}
}
}
}
现在 TestMethodAfterClose 成功并且 TestMethodAfterFlush 失败。当我使用程序BareTail 并在断点处等待时,我看到它在文件关闭之前更新了显示。所以这给了我一个迹象,表明这是可能的。我不知道在 C# 中是否可行,我可能需要使用 dllimport 导入一些本机函数。问题是我不知道去哪里看
如何在不使用计时器的情况下使两个测试都成功?
编辑: 更新了 FileWatcherTest 类
【问题讨论】:
-
你在检查异常吗?在我看来,由于共享冲突,尝试在文件观察程序中打开文件以在测试中写入时会失败。
-
在我自己的代码中我这样做了,但是除了由失败的断言引起的异常之外,我知道没有抛出异常。我在这个问题中查找的文件共享问题:stackoverflow.com/questions/4400517/…
-
@500-InternalServerError 为写入而打开的文件在共享模式正确的情况下打开用于读取时应该不会造成任何问题。
标签: c# dllimport filesystemwatcher