我正在使用名为ReactiveFileSystemWatcher
的NuGet包,其中ObservableFileSystemWatcher
是FileSystemWatcher
周围的可观察包装。
我的文本文件不断添加新内容,我想只获取delta更改。
下面的代码会在文件内容发生变化时发出通知,但我想要附加到该文件的内容是什么?
using RxFileSystemWatcher;
using System;
using System.Linq;
using System.Reactive.Linq;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
using (var watcher = new ObservableFileSystemWatcher(c => { c.Path = @"C:\Test\"; c.IncludeSubdirectories = true; }))
{
watcher.Changed.Select(x => $"{x.Name} was {x.ChangeType}").Subscribe(Console.WriteLine);
watcher.Start();
Console.ReadLine();
}
}
}
}
答案 0 :(得分:2)
如果你知道文件总是只附加到,并且中间的任何地方都没有发生任何变化,你可以通过跟踪你正在观看的所有文件的长度来解决这个问题。如果有变化,您只需将文件内容从旧长度读取到文件的新结尾。
Dictionary<string, long> lengthByFilename = new Dictionary<string, long>();
// TODO: recurse through all existing files to get their lengths and put in
// the dictionary
watcher.Changed.Select(x => {
string addedContent;
using (var file = File.OpenRead(x.Name)) {
// Seek to the last known end position
if (lengthByFilename.ContainsKey(x.Name)) {
file.Seek(lengthByFilename[x.Name], SeekOrigin.Begin);
}
using (var reader = new StreamReader(file)) {
addedContent = reader.ReadToEnd();
}
}
// Update dictionary with new length
lengthByFilename[x.Name] = (new FileInfo(x.Name)).Length;
return $"{x.Name} has had this added: {addedContent}";
}).Subscribe(Console.WriteLine);
显然,这段代码严重缺乏错误处理,但它是一个开始。您必须捕获IOExceptions并考虑如何以正确的方式处理锁定的文件。您可能需要实现一个事件队列,您可以迭代这些事件以尝试重新尝试阅读新内容。