【问题标题】:Reading file, and monitor new line读取文件,并监控新行
【发布时间】:2014-04-26 02:56:36
【问题描述】:

我正在寻找创建一个控制台应用程序,它将读取一个文件,并监视每个新行,因为它每 0.5 秒被另一个进程写入一次。

如何在使用 .NET 4.5 的控制台应用程序中实现这一点?

【问题讨论】:

    标签: c# .net console-application filestream


    【解决方案1】:

    听起来您想要一个适用于 Windows 的 tail 版本。请参阅“Looking for a windows equivalent of the unix tail command”进行讨论。

    否则,open the file 不会阻止其他进程使用FileShare.ReadWrite 进行访问。寻找到最后阅读,然后使用Thread.Sleep()Task.Delay() 等待半秒钟,看看是否有任何变化。

    例如:

    public static void Follow(string path)
    {
        // Note the FileShare.ReadWrite, allowing others to modify the file
        using (FileStream fileStream = File.Open(path, FileMode.Open, 
            FileAccess.Read, FileShare.ReadWrite))
        {
            fileStream.Seek(0, SeekOrigin.End);
            using (StreamReader streamReader = new StreamReader(fileStream))
            {
                for (;;)
                {
                    // Substitute a different timespan if required.
                    Thread.Sleep(TimeSpan.FromSeconds(0.5));
    
                    // Write the output to the screen or do something different.
                    // If you want newlines, search the return value of "ReadToEnd"
                    // for Environment.NewLine.
                    Console.Out.Write(streamReader.ReadToEnd());
                }
            }
        }
    }
    

    【讨论】:

    • 与 CryptoStream-FileStream 一起使用时,StreamReader 会以某种方式停止。似乎当 File-stream 增长时不会通知 CryptoStream!
    【解决方案2】:

    正如@Sudhakar 所提到的,当您希望在文件偶尔更新时收到通知时,FileSystemWatcher 很有用,而当您希望不断处理来自始终增长的文件(例如繁忙的日志)中的信息时,定期轮询很有用文件)。

    我想补充一点关于效率的说明。如果您关心处理大文件(许多 MB 或 GB)的效率和速度,那么您将希望在阅读和处理更新时跟踪您在文件中的位置。例如:

    // This does exactly what it looks like.
    long position = GetMyLastReadPosition();
    
    using (var file = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    {
        if (position == file.Length)
            return;
    
        file.Position = position;
        using (var reader = new StreamReader(file))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                // Do reading.
            }
            position = file.Position; // Store this somewhere too.
        }
    }
    

    这应该允许您避免重新处理您已经处理过的文件的任何部分。

    【讨论】:

    • 您可以保留文件流和流阅读器以备将来调用,无需重新打开。我错过了什么吗?
    【解决方案3】:

    解决方案一:你可以使用FileSystemWatcher

    来自 MSDN:

    使用 FileSystemWatcher 监视指定目录中的更改。 您可以观察指定的文件和子目录的变化 目录。您可以创建一个组件来监视本地文件 计算机、网络驱动器或远程计算机。

    解决方案 2:您可以通过创建 Timer 并每 5 秒读取文件内容来使用 Polling

    【讨论】:

    • 对于在 1 小时内从 1 Ko 增长到 88 Mo 的文本文件,FileSystemWatcher 真的有效吗?我不想每秒都重新解析文件。
    • @Dekim:那个文件在哪里?在网络驱动器上?
    • 本地!尽管我有很多逻辑,所以不要两次解析同一行。
    • @Dekim:我认为如果您使用本地文件,您不会发现任何困难。
    • +1。请注意,您需要 akton (+1) 的答案中涵盖的后半部分(从 2 个进程打开文件)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    • 1970-01-01
    • 2022-06-24
    相关资源
    最近更新 更多