必威体育Betway必威体育官网
当前位置:首页 > IT技术

C# 使用FileSystemWatcher类来对一个日志文件的变化进行实时监测

时间:2019-08-17 10:40:00来源:IT技术作者:seo实验室小编阅读:84次「手机版」
 

filesystemwatcher

C# 使用FileSystemWatcher类来对一个日志文件的变化进行实时监测

应用场景描述:在我的工作中,遇到这么一个情况,有一个没有源码的程序A,用来读取设备的状态信息,然后将这个状态信息写入一个txt日志文件中。我想要通过实时的读取日志文件的变化信息来将这个设备的状态信息提取出来。

发现使用C# FileSystemWatcher这个类的Changed这个事件可以很好的实现这个功能。它在文件发生变化时可以及时的检测到这个文件。

开发过程中遇到的问题:

1. 这个程序经常同时(时间点很近)读取多个设备的信息,而由于对日志文件的处理时间,所以经常不能触发足够的次数。例如,程序A往日志文件中同时写入10条数据,但是Changed这个事件可能只触发了5次。

2. 由于日志文件的写操作不受我们的控制,因此,我们希望文件的读写操作可以共享

C# 控制台代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.regularexpressions;
using System.configuration;
namespace ReadTxt
{
class Program
{
        private static string lastData = string.empty;//用来表示上一次读取到的最后一条数据
        static void Main(string[] args)
        {            
            FileSystemWatcher watcher = new FileSystemWatcher("path"));//注意:这里的path是文件夹路径,不包含文件名
            watcher.EnableRaisingEvents = true;
            watcher.IncludeSubdirectories = true;
            watcher.Changed += new FileSystemeventhandler(watcher_Changed);//文件变化时触发的事件      
        }
        private static void watcher_Changed(object sender, FileSystemEventArgs e)
        {
            (sender as FileSystemWatcher).EnableRaisingEvents = false;
            (sender as FileSystemWatcher).EnableRaisingEvents = true;//这样可以保证changed事件可以被重新触发。
            //启用一个任务线程来尽可能的减少changed事件处理时间
            System.Threading.Tasks.Task.Factory.StartNew(() =>
            {
                List<string> list = new List<string>();
                string strReg = "regularexpression";//正则表达式字符串,用于将对文件进行筛选,
                if (Regex.IsMatch(e.Name, strReg))
                {
                    lock (lastData)//锁定lastData,防止多个任务线程同时访问时造成lastData值的错乱
                    {
                        filestream fs = File.Open("path" + e.Name, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                        streamreader sr = new StreamReader(fs);//流读取器
                        try
                        {
                            //如果listData为空,则表示第一次读去变化的文件夹,这里我们默认读取到一个设备,具体到实际的项目中可以再更改
                            if (lastData == string.Empty)
                            {
                                string s = string.Empty;
                                while (!sr.EndOfStream)
                                {
                                    s = sr.ReadLine();
                                    lastData = s;
                                }
                            }
                            else//否则,从listData开始,取后面的所有数据加入list中
                            {
                                string s = string.Empty;
                                do
                                {
                                    s = sr.ReadLine();
                                } while (s != lastData);
                                while (!sr.EndOfStream)
                                {
                                    s = sr.ReadLine();
                                    list.Add(s);                                    
                                }
                            }                                                                                    
                            foreach (var str in list)
                            {
                                lastData = str;
                                DoWork(lastData)//这个函数可以自己写,用来处理数据                               
                            }
                        }                        
                        catch (Exception ex)
                        {
                            //。。。处理错误
                        }
                        finally
                        {
                            sr.Close();
                            fs.Close();
                        }
                    }
                }
            });
        }
    }
    }

这个代码目前能实现了我想要的功能,但是应该还有一些可以改进的地方,大家可以自己试一试,尤其是changed事件的重新触发和流文件这块。

相关阅读

php7 Session_start()函数的变化-------每天进步一点

php7以前,我们使用session前都是要先代用session_strat()函数来初始化的,但这个函数是没有参数可以传的,session的配置都在php.ini文

SAP新的Activate实施方法论都有什么变化

SAP Activate包含SAP最佳实践、向导式配置和实施方法论三部分内容。其中Activate实施方法论继承了ASAP的部分内容,也加入了新的指

使用百度地图api模拟实时定位页面 完整示例

使用百度地图api模拟实时定位页面 完整示例 效果:使用百度地图api在页面上显示车辆的实时位置,并有自动刷新和手动刷新两种方

ScaleAnimation类:尺寸变化动画类

9.4  ScaleAnimation类:尺寸变化动画类ScaleAnimation类是Android系统中的尺寸变化动画类,用于控制View对象的尺寸变化,该类继承于A

谁说Axure 9.0没有创新?深度体验后,竟发现了39处变化

美国时间2018年9月5日Axure RP 9.0 Betal版在官方博客首次对外公布,一时间引来了不少全球Axure粉丝的围观与下载。作为Axure资深用

分享到:

栏目导航

推荐阅读

热门阅读