文件夹监控源码(API函数ReadDirectoryChangesW 监视目录)

来源:互联网 发布:aws s3 上传文件 java 编辑:程序博客网 时间:2024/06/01 07:57

对指定的一个目录进行监控,当该目录中有文件发生改变,并通知处理。 Windows提供了对文件和目录监控的系统服务,并且为应用程序提供了两个API函数,它们分别是:FindFirstChangeNotification和ReadDirectoryChangesW。由于通过FindFirstChangeNotification函数只能监控到某一目录下有文件发生改变,而不能监控到具体是哪一文件发生改变,所以本人选用ReadDirectoryChangesW函数。使用ReadDirectoryChangesW函数,这个函数不仅能够监测到文件系统的变化,还能够返回详细的文件变动的信息,并且能够选择是使用同步方式检测还是异步方式监测,比较全面,但是这个函数的使用比较复杂,而且有一些需要注意的地方.

 

函数定义:

BOOL WINAPI ReadDirectoryChangesW(

  __in  HANDLE hDirectory, 要监控的目录句柄, 必须有FILE_LIST_DIRECTORY访问权限。

  __out LPVOID lpBuffer, 返回信息指针, 定义为FILE_NOTIFY_INFORMATION结构。

  __in  DWORD nBufferLength, lpBuffer内存的长度。

  __in  BOOL bWatchSubtree, 是否监控子目录。

  __in  DWORD dwNotifyFilter, 过滤参数配置。

  __out_opt   LPDWORD lpBytesReturned, 实际lpBuffer内存的长度。

  __inout_opt LPOVERLAPPED lpOverlapped, 异步使用时指向一个OVERLAPPED结构指针;同步使用等其他情况为NULL其中该结构中的OffsetOffsetHigh成员并没有使用。

  __in_opt    LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine

操作完成或取消时的返回函数,更多信息参考FileIOCompletionRoutine

);

 

 

dwNotifyFilter [in] 过滤参数配置

The filter criteria that the function checks to determine if the wait operation has completed. This parameter can be one or more of the following values.

Value

Meaning

FILE_NOTIFY_CHANGE_FILE_NAME

0x00000001

Any file name change in the watched directory or subtree causes a change notification wait operation to return. Changes include renaming, creating, or deleting a file.

FILE_NOTIFY_CHANGE_DIR_NAME

0x00000002

Any directory-name change in the watched directory or subtree causes a change notification wait operation to return. Changes include creating or deleting a directory.

FILE_NOTIFY_CHANGE_ATTRIBUTES

0x00000004

Any attribute change in the watched directory or subtree causes a change notification wait operation to return.

FILE_NOTIFY_CHANGE_SIZE

0x00000008

Any file-size change in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change in file size only when the file is written to the disk. For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.

FILE_NOTIFY_CHANGE_LAST_WRITE

0x00000010

Any change to the last write-time of files in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change to the last write-time only when the file is written to the disk. For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.

FILE_NOTIFY_CHANGE_LAST_ACCESS

0x00000020

Any change to the last access time of files in the watched directory or subtree causes a change notification wait operation to return.

FILE_NOTIFY_CHANGE_CREATION

0x00000040

Any change to the creation time of files in the watched directory or subtree causes a change notification wait operation to return.

FILE_NOTIFY_CHANGE_SECURITY

0x00000100

Any security-descriptor change in the watched directory or subtree causes a change notification wait operation to return.

 

返回值:

函数执行成功返回值非0,失败时为0。若网络重定向或目标文件系统不支持该操作,函数失败,同时调用GetLastError()返回ERROR_INVALID_FUNCTION

第一个参数是要监控目录的句柄,获取监控目录句柄,使用CreateFile指定FILE_FLAG_BACKUP_SEMANTICS .用户代码通过第二个和第三个参数来告知操作系统该把目录变化通知放在首地址为返回信息指针, 一块内存长度区域当中的。但是该内存又是怎样组织的呢?操作系统是把他们放在FILE_NOTIFY_INFORMATION这个结构里面的:

typedef struct _FILE_NOTIFY_INFORMATION {
  DWORD NextEntryOffset;
  DWORD Action;
  DWORD FileNameLength;
  WCHAR FileName[1];
} FILE_NOTIFY_INFORMATION, *PFILE_NOTIFY_INFORMATION;

NextEntryOffset

The number of bytes that must be skipped to get to the next record. A value of zero indicates that this is the last record.(要获得下一个记录需要跳过多少字节数,如果它的值为0,就表示本记录已经是最后一条记录了。该字段其实也可以看作是一个指向下一条记录的指针。)

Action

The type of change that has occurred. This member can be one of the following values.(本次通知了哪种类型的变化)

ValueMeaning
FILE_ACTION_ADDED
0x00000001

The file was added to the directory.

FILE_ACTION_REMOVED
0x00000002

The file was removed from the directory.

FILE_ACTION_MODIFIED
0x00000003

The file was modified. This can be a change in the time stamp or attributes.

FILE_ACTION_RENAMED_OLD_NAME
0x00000004

The file was renamed and this is the old name.

FILE_ACTION_RENAMED_NEW_NAME
0x00000005

The file was renamed and this is the new name.

 

FileNameLength

The size of the file name portion of the record, in bytes. Note that this value does not include the terminating null character.(变化的文件名称的长度,不包含终止符。)

FileName

A variable-length field that contains the file name relative to the directory handle. The file name is in the Unicode character format and is not null-terminated.

If there is both a short and long name for the file, the function will return one of these names, but it is unspecified which one.(一个存放变化的文件名称的Unicode字符数组的首地址

 

另外一个与本函数有关的参数是类型过滤器。它是目录变化通知过滤器。要监控文件名发生变化,此参数应设为FILE_NOTIFY_CHANGE_FILE_NAME;文件被非法改写为FILE_NOTIFY_CHANGE_LAST_WRITE等等。根据过滤器的设置,ReadDirectoryChangesW函数可以监控文件名改变、文件属性改变、文件大小改变、文件内容被改写、文件被删除等多种类型的变化。

  利用ReadDirectoryChangesW函数实现对一个目录进行监控的。具体的做法是:首先使用CreateFile获取要监控目录的句柄;然后在一个判断循环里面调用ReadDirectoryChangesW,并且把自己分配的用来存放目录变化通知的内存首地址、内存长度、目录句柄传给该函数。用户代码在该函数的调用中进行同步等待。当目录中有文件发生改变,控制函数把目录变化通知存放在指定的内存区域内,并把发生改变的文件名、文件所在目录和改变通知处理。

原创粉丝点击