C# 使用FileSystemWatcher类来对一个日志文件的变化进行实时监测
2023-09-11 14:22:03 时间
C# 使用FileSystemWatcher类来对一个日志文件的变化进行实时监测
2018年08月09日 13:33:01 loveljy_19901114 阅读数:1035
应用场景描述:在我的工作中,遇到这么一个情况,有一个没有源码的程序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事件的重新触发和流文件这块。
相关文章
- 使用C#创建快捷方式
- (C#)Application.Exit()、Environment.Exit(0)区别
- 《C#高级编程》学习笔记----c#内存管理--栈VS堆
- C#.NET常见问题(FAQ)-想要另存一个项目,sln文件丢了怎么办,如何打开高版本的项目
- C#.NET常见问题(FAQ)-程序如何把窗体文件从从一个项目中复制到另一个项目
- 使用C#调用旋风快车和迅雷下载文件 也是C#调用Com的好例子!
- C#实现文件下载的几种方式
- C#Winform中resx文件无效 找不到路径
- C# 文件操作 把文件读取到字节数组
- ActiveMQ C#消息队列系列一(安装)
- C# 下利用ICSharpCode.SharpZipLib.dll实现文件/文件夹压缩、解压缩
- C# 获取选择文件信息
- C#中正则表达式的使用
- [转] C#实现在Sql Server中存储和读取Word文件 (Not Correct Modified)
- C# 下利用ICSharpCode.SharpZipLib.dll实现文件/文件夹压缩、解压缩
- 【原创】开源Math.NET基础数学类库使用(17)C#计算矩阵条件数
- atitit.跨语言实现备份mysql数据库 为sql文件特性 api 兼容性java c#.net php js
- Atitit。Tree文件解析器的原理流程与设计实现 java c# php js
- Atitit,通过pid获取进程文件路径 java php c#.net版本大总结
- C# 正则表达式
- [h5棋牌项目]-16-C#写json文件
- c# - Document编辑office的doc或者docx文件表格指定格子内容并保存-自定义工具
- (六十五)c#Winform自定义控件-思维导图/组织架构图(工业)-HZHControls
- (六)c#Winform自定义控件-单选框-HZHControls
- C#+无unsafe的非托管大数组(large unmanaged array in c# without 'unsafe' keyword)
- (7)C#的this关键字的三种用法
- c# ThreadPoold使用心得
- .NET(C#) 读取Resource资源文件的方法
- c#实现内存映射文件共享内存
- C#winform各种异常处理方式