文件监视:
windows:
方法(一):
利用FindFirstChangeNotification(),WaitForSingleObject(),FindNextChangeNotificion
(),FindCloseChangeNotification()等函数;
demo:
//thread
void ThreadRoute( void* arg )
{
HANDLE file;
file = FindFirstChangeNotification("c://Program Files", FALSE, arg);
WaitForSingleObject(file, INFINITE);
CTime tm = CTime::GetCurrentTime();
m_Sec.Lock();
int item = pList->InsertItem(pList->GetItemCount(), ((Param*)arg)->message);
pList->SetItemText(item, 1, tm.Format("%Y/%m/%d - %H:%M:%S"));
m_Sec.Unlock();
while (true)
{
FindNextChangeNotification(file);
WaitForSingleObject(file, INFINITE);
tm = CTime::GetCurrentTime();
m_Sec.Lock();
int item = pList->InsertItem(pList->GetItemCount(), arg);
pList->SetItemText(item, 1, tm.Format("%Y/%m/%d/ - %H:%M:%S"));
m_Sec.Unlock();
}
FindCloseChangeNotification(file);
}
方法(二):
利用ReadDirectoryChangeW().
demo:
void ThreadRoute1( void* arg )
{
USES_CONVERSION;
HANDLE hDir = CreateFile( CString("c://Program Files"), // pointer to the file name
FILE_LIST_DIRECTORY, // access (read/write) mode
FILE_SHARE_READ|FILE_SHARE_DELETE, // share mode
NULL, // security descriptor
OPEN_EXISTING, // how to create
FILE_FLAG_BACKUP_SEMANTICS, // file attributes
NULL // file with attributes to copy
);
FILE_NOTIFY_INFORMATION Buffer[1024];
DWORD BytesReturned;
while( ReadDirectoryChangesW(
hDir, // handle to directory
&Buffer, // read results buffer
sizeof(Buffer), // length of buffer
TRUE, // monitoring option
FILE_NOTIFY_CHANGE_SECURITY|
FILE_NOTIFY_CHANGE_CREATION|
FILE_NOTIFY_CHANGE_LAST_ACCESS|
FILE_NOTIFY_CHANGE_LAST_WRITE|
FILE_NOTIFY_CHANGE_SIZE|
FILE_NOTIFY_CHANGE_ATTRIBUTES|
FILE_NOTIFY_CHANGE_DIR_NAME|
FILE_NOTIFY_CHANGE_FILE_NAME, // filter conditions
&BytesReturned, // bytes returned
NULL, // overlapped buffer
NULL// completion routine
))
{
CTime tm = CTime::GetCurrentTime();
CString helper_txt;
switch(Buffer[0].Action)
{
case FILE_ACTION_ADDED: helper_txt = "The file was added to the directory"; break;
case FILE_ACTION_REMOVED: helper_txt = "The file was removed from the directory"; break;
case FILE_ACTION_MODIFIED: helper_txt = "The file was modified. This can be a change in the time stamp
or attributes."; break;
case FILE_ACTION_RENAMED_OLD_NAME: helper_txt = "The file was renamed and this is the old name.";
break;
case FILE_ACTION_RENAMED_NEW_NAME: helper_txt = "The file was renamed and this is the new name.";
break;
}
int i=0;
do
{
m_Sec.Lock();
int item = pList1->InsertItem(pList1->GetItemCount(), CString(Buffer[i].FileName).Left(Buffer
[i].FileNameLength / 2) + " - " + helper_txt );
pList1->SetItemText(item, 1, tm.Format("%Y/%m/%d/ - %H:%M:%S"));
i++;
m_Sec.Unlock();
}
while (!Buffer[i].NextEntryOffset);
}
}
Linux:
利用inotify工具
demo:
type:
//MonitorObject
typedef struct _tagMonitorObject
{
//int nIndex;//索引
char path[512];//索引对应的名字
char object[512];//监视器对象
int nProty;//监视属性
int wd;//MONITOR描述
}MonitorObject;
//MonitorLog
typedef struct _tagMonitorLog
{
char path[512];//路径
char object[512];//监视器对象
char eventobj[64];//事件对象
char eventmsg[128];//事件信息
char stype[10];//文件夹 还是文件
char time[80];//时间时间
}MonitorLog;
Fun():
m_FileID = inotify_init();
wd = inotify_add_watch(m_FileID,object,m_nProperty);
inotify_rm_watch(m_FileID,wd);
int CFileMonitor::FindDir(const char* name,const char* path,int ntype)
{
if(name == NULL) return 0;
int nRet = 0;
DIR *fdir;
struct dirent *pdir;
if((fdir=opendir(name))==NULL)
{
printf("打开错误! errno = %d ,/n",errno);
nRet == errno;
return nRet;
}
while((pdir=readdir(fdir))!=NULL)
{
if( *pdir->d_name == '.' /*|| *pdir->d_name[0] == '..'*/)
continue;
if(pdir->d_type == DT_DIR)
{
char pathname[512] = {0};
snprintf(pathname,512,"%s/%s",name,pdir->d_name);
printf("pathname = %s /n",pathname);
if(ntype == 1)
{
AddMonitorObject(1,pathname,path);
}
else if(ntype == 2)
{
char sqlCmd[1024] = {0};
//删除监视器下
snprintf(sqlCmd,1024,"select * from [TMonitorobject] where [object] = '%s'",pathname);
nRet = CConfigAdapter::ExecSql(sqlCmd,DelMonitorObjectCallback,this);
//删除数据库
memset(sqlCmd,0,1024);
snprintf(sqlCmd,1024,"delete from [TMonitorobject] where [path] = '%s'",pathname);
nRet = CConfigAdapter::ExecSql(sqlCmd,NULL,NULL);
}
else
{
printf("ntype 错误/n ");
break;
}
FindDir(pathname,path,ntype);
}
}
closedir(fdir);
return nRet;
}
//阻塞函数
int CFileMonitor::GetEvent(PFun_Get_Event pfun)
{
int nRet = -1;
char buffer[MAX_BUF_SIZE] = {0};
struct inotify_event * event;
int len, tmp_len;
char* offset = NULL;
char sqlCmd[512]={0};
char object[512] = {0};
int wd ;
while(!m_bExit)
{
memset(buffer,0,MAX_BUF_SIZE);
fd_set fds;
FD_ZERO(&fds);
struct timeval tv = {3,0};
FD_SET(m_FileID,&fds);
nRet = select(m_FileID + 1,&fds,NULL,NULL,&tv);
int length = 0;
if( ( nRet > 0 ) && (FD_ISSET(m_FileID,&fds) > 0) )
{
length = read(m_FileID,buffer,MAX_BUF_SIZE);
event = (struct inotify_event*)buffer;
offset = buffer;
while(offset - buffer < length)
{
MonitorLog log;
char *tmp = new char[event->len + 1];
memcpy(tmp,&event->name,len);
tmp[event->len] = 0;
//printf("mask = %d, wd = %d , eventmsg = %s /n",event->mask,event->wd,event->name);
//获取对象名称
memset(object,0,512);
memset(sqlCmd,0,512);
wd = event->wd;
//查数据库
snprintf(sqlCmd,512,"select * from [TMonitorobject] where [wd]=%d",wd);
NameAObject no;
CConfigAdapter::ExecSql(sqlCmd,GetMonitorObject,&no);
snprintf(log.path,512,"%s",no.path);
snprintf(log.object,512,"%s",no.object);
memcpy(log.eventobj,&event->name,event->len);
if(event->mask &IN_ISDIR)
{
strcpy(log.stype,"Directory");
}
else
{
strcpy(log.stype,"File");
}
if(event->mask & IN_MODIFY)
{
snprintf(log.eventmsg,128,"%s","modified");
(*pfun)(&log);
}
if(event->mask & IN_MOVED_FROM)
{
strcpy(log.eventmsg,"moved from object name");
(*pfun)(&log);
}
if(event->mask & IN_MOVED_TO)
{
strcpy(log.eventmsg,"moved to ...");
(*pfun)(&log);
}
if(event->mask & IN_CREATE)
{
strcpy(log.eventmsg,"created");
(*pfun)(&log);
}
if(event->mask & IN_DELETE )
{
strcpy(log.eventmsg,"deleted");
pfun(&log);
}
if(event->mask & IN_ATTRIB)
{
strcpy(log.eventmsg,"attrib changed");
pfun(&log);
}
offset += sizeof(struct inotify_event) + event->len;
event = (struct inotify_event*)offset;
delete[]tmp;
tmp = NULL;
}
}
}
return nRet;
}