监控log文件变化进行读出变化的内容供分析的源码类

监控log文件变化进行读出变化的内容供分析的源码类
头文件:
#pragma once

//#define  DEBUG_MONITORING_FILE_CHANGES
#ifdef DEBUG_MONITORING_FILE_CHANGES
#include "CiteConsole.h"
#endif


//定义获取到新的内容事件
typedef void (CALLBACK* ONREADNEWCONTENT)(void* pOwner, const CString* strBuf, DWORD dwBufLen);

class CLogFileMonitor
{
public:
	CLogFileMonitor(void);
public:
	~CLogFileMonitor(void);

	/*--向上层的回调事件--*/
	//读取到新的数据事件,回调函数
	ONREADNEWCONTENT OnReadNewContent;

private:
	//线程退出事件句柄
	HANDLE m_exitThreadEvent; 
	//线程句柄
	HANDLE m_MonitoringThreadHandle;
	//父对象句柄
	void * m_pOwner;

private:
	static DWORD WINAPI  MonitoringThreadFunc(LPVOID lparam);	
	BOOL Close();

	// 文件读取的成员和方法
private:
	LONGLONG m_lOff; //记录读取的文件的位置
	ULONGLONG m_lActual;//seek实际到达的文件位置

	CString m_strFilePathName;
	CStdioFile m_file;
	BOOL m_blOpenSucess;
	void OpenFile();
	void ReadNewLine();

public:
	void Init(CString strFileName, void* pOwner, void* OnReadNewContentFun);

};

源文件
#include "StdAfx.h"
#include "LogFileMonitor.h"

CLogFileMonitor::CLogFileMonitor(void)
{
	OnReadNewContent = NULL;
	m_pOwner = NULL;

	m_lOff = 0;
	m_lActual = 0;
	m_blOpenSucess =FALSE;

	//创建线程退出事件句柄
	CString strEventName;
	strEventName.Format(_T("EVENT_FILE_MONITOR_THREAD%d"), this);
	m_exitThreadEvent = CreateEvent(NULL,FALSE,FALSE, strEventName);
	//创建通讯线程
	m_MonitoringThreadHandle = CreateThread(NULL,0,MonitoringThreadFunc,this,0,NULL);
}

CLogFileMonitor::~CLogFileMonitor(void)
{
	Close();
	//关闭线程退出事件句柄
	CloseHandle(m_exitThreadEvent);
	Sleep(1000);

	if (m_blOpenSucess && m_file )
	{
		m_file.Close();
		printf("文件关闭");
		m_blOpenSucess = FALSE;
	}
	m_blOpenSucess =FALSE;
}

DWORD WINAPI CLogFileMonitor::MonitoringThreadFunc(LPVOID lparam)
{
	CLogFileMonitor *pThis = (CLogFileMonitor*)lparam;

	while (TRUE)
	{
		//收到退出事件,结束线程
		if (WaitForSingleObject(pThis->m_exitThreadEvent,0) == WAIT_OBJECT_0)
		{
			break;
		}

		pThis->ReadNewLine();

	}
	TRACE(L"CMonitoringFileChanges线程退出\n");
	return 0;
}

void CLogFileMonitor::Init(CString strFileName,void* pOwner, void* OnReadNewContentFun)
{
	m_strFilePathName = strFileName;
	m_pOwner = pOwner;
	OnReadNewContent = (ONREADNEWCONTENT)OnReadNewContentFun;
}


void CLogFileMonitor::OpenFile()
{
	m_blOpenSucess =  m_file.Open(m_strFilePathName, CFile::modeRead |CFile::shareDenyNone);
	if (!m_blOpenSucess)
	{
		printf("监控log文件失败");
	}
}

void CLogFileMonitor::ReadNewLine()
{
	if(!m_blOpenSucess)
	{
		Sleep(100);
		OpenFile();
		if (!m_blOpenSucess)
		{
			return;
		}
	}


	if (m_lOff != m_lActual)
	{
		Sleep(200);
	}
	else
	{
		Sleep(300);
	}

	CString strText = _T("");
	CString szLine = _T("");
	
	if (m_file ==NULL)
	{
		return;
	}

	if (!m_blOpenSucess)
	{
		return;
	}

	if (m_file.m_pStream != NULL)
	{
		m_lActual =  m_file.Seek(m_lOff,CFile::begin);
		//逐行读取字符串
		while( m_file.ReadString( szLine ) )
		{
			if (m_pOwner && !szLine.IsEmpty())
			{
				OnReadNewContent(m_pOwner, &szLine, m_lActual);
			}
			szLine = _T("");
		}

		m_lOff = m_file.Seek(0, CFile::current);
	}
}

BOOL CLogFileMonitor::Close()
{
	//发送通讯线程结束事件
	SetEvent(m_exitThreadEvent);

	//等待1秒,如果读线程没有退出,则强制退出
	if (WaitForSingleObject(m_MonitoringThreadHandle,1000) == WAIT_TIMEOUT)
	{
		TerminateThread(m_MonitoringThreadHandle,0);
		TRACE(L"强制终止客户端线程\n");
	}
	m_MonitoringThreadHandle = NULL;
	//关闭文件,释放资源

	return TRUE;
}


使用的时候,实现回调就可以在回调里面获取最新获取的变化量;
还有可以改进的思路就是:
每次都进行打开,并且每次都关闭,这样可以尽量不影响原来其他程序对log文件的操作。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零点零一

您的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值