【问题标题】:How to read last inserted lines in a txt file with C#?如何使用 C# 读取 txt 文件中最后插入的行?
【发布时间】:2022-01-01 03:47:11
【问题描述】:

我的目标是从 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 读取插入的数据。任何帮助都会非常显着。

【问题讨论】:

  • 也许:当事件被触发时,以字节为单位存储文件的大小。下次触发时,文件的新大小减去旧大小就是添加/删除的字节数。
  • 感谢您的回复。但我需要阅读最后添加到文本文件中的文本。

标签: c# console txt


【解决方案1】:

FileSystemWatcher 用于监视文件系统更改而不是文件内容更改。 Changed 事件将在被监视的条目发生变化时触发,这会在文件大小增加时发生。因此,文件内容更改与事件之间存在联系。但你必须明白,这不是因为文件发生了变化,而是因为描述文件的某些元数据的文件系统条目发生了变化。

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

【讨论】:

    【解决方案2】:

    我认为现在它会起作用:

    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 文件夹)附近,它肯定会工作。

    【讨论】:

    • 如果同时添加多行会怎样?
    • @CodeStranger 它可以工作,但它会因错误'进程无法访问文件'file.txt',因为它正在被另一个进程使用而中断。'
    • @CodeStranger 一切正常(至少如果文件在调试文件夹中)
    • @Dori 谢谢你的回复。正如 CodeStranger 提到的,我对您的代码有一个问题。如果添加多行,则只有其中的最后一行。
    • @AloukikRoy 我做了一些改变,试试看。我希望你不要在运行时更改以前的文本。
    【解决方案3】:

    如果你的文件不是那么大:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-24
      • 2021-09-13
      • 1970-01-01
      • 2013-04-05
      • 2019-03-02
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      相关资源
      最近更新 更多