如何获取文件的delta内容

时间:2018-01-24 15:05:14

标签: c# system.reactive

我正在使用名为ReactiveFileSystemWatcher的NuGet包,其中ObservableFileSystemWatcherFileSystemWatcher周围的可观察包装。

我的文本文件不断添加新内容,我想只获取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();
        }
    }

}
}

1 个答案:

答案 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并考虑如何以正确的方式处理锁定的文件。您可能需要实现一个事件队列,您可以迭代这些事件以尝试重新尝试阅读新内容。