如何使用 C# 读取 txt 文件中最后插入的行?

How to read last inserted lines in a txt file with C#?

我的目标是从 txt 文件中读取最后插入的行,并在控制台中仅显示新插入的行。这是我的代码-

class Program
    {
        static void Main(string[] args)
        {
            string path = @"D:\tmp";

            MonitorFile(path);

            Console.ReadKey();
        }

        private static void MonitorFile(string path)

        { 

            FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();

            fileSystemWatcher.Path = path;

            fileSystemWatcher.Filter = "file.txt";

            fileSystemWatcher.Changed += FileSystemWatcher_Changed;

            fileSystemWatcher.EnableRaisingEvents = true;

        }

        private static void FileSystemWatcher_Changed(object sender, FileSystemEventArgs e)

        {
            Console.WriteLine("");    //From here new inserted lines should be showed on the console.
        }
    }

我的目标是每次在文本文件的最后添加新行并且只有插入的新行才会在控制台中一个接一个地出现。在这里,我使用 FileSystemWatcher 来识别 txt 文件中的更改,但似乎无法从 FileSystemWatcher 读取插入的数据。任何帮助都将非常宝贵。

FileSystemWatcher 用于观察文件系统变化而不是文件内容变化。 Changed 如果监视的条目发生变化,将触发事件,如果文件大小增加,则会发生这种情况。所以文件内容变化和事件之间存在联系。但是您必须了解这不是因为文件更改而是因为描述文件元数据的文件系统条目发生了更改。

如果您需要更改文件中添加的行,则通过 FileStream 打开文件并在 Changed 事件处理程序中读取它。我会在没有锁的情况下以只读模式打开文件,因此写入它的其他进程不会因此而被阻塞。如果你只需要附加的行然后使用其他人建议的技术:保存你看到的最后一个文件 Position 并且下次打开文件后只需搜索那个位置,阅读直到新闻结束然后再次保存当前位置。

如果你的文件不是很大:

File.ReadLines(@"c:\file.txt").Last();

我想现在可以了:

class Program
{
    public static string lastValue = string.Empty;
    public static string folderPath = AppDomain.CurrentDomain.BaseDirectory;
    public static string fileName = "file.txt";

    static void Main(string[] args)
    {
        MonitorFile(folderPath);
        Console.ReadKey();
    }

    private static void MonitorFile(string path)
    {
        lastValue = File.ReadAllLines(folderPath + fileName).Last();
        FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();
        fileSystemWatcher.Path = path;
        fileSystemWatcher.Filter = fileName;
        fileSystemWatcher.Changed += FileSystemWatcher_Changed;
        fileSystemWatcher.EnableRaisingEvents = true;
    }

    private static void FileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
    {
        if (e.ChangeType != WatcherChangeTypes.Changed)
        {
            return;
        }

        var numberOfRetries = 3;
        var delayOnRetry = 500;

        for (int i = 1; i <= numberOfRetries; ++i)
        {
            try
            {
                var lines =  File.ReadAllLines(folderPath + fileName).ToList();
                var lastLine = lines.Last();

                if (lastLine != lastValue)
                {
                    var index = lines.LastIndexOf(lastValue) + 1;
                    var newLines = lines.GetRange(index, lines.Count - index);
                    lastValue = newLines.Last();
                    newLines.ForEach(Console.WriteLine);
                }
                break; 
            }
            catch (IOException) when (i <= numberOfRetries)
            {
                Thread.Sleep(delayOnRetry);
            }
        }
    }
}

但是这里可能权限有问题。 如果将 folderPath 更改为:

public static string folderPath = AppDomain.CurrentDomain.BaseDirectory;

并将您的文件放在 DLL 文件附近(bin\Debug 文件夹),它肯定会工作。