上一章讲到监控文件变化之函数 ReadDirectoryChangesW 要用到结构体FILE_NOTIFY_INFORMATION
该结构体定义如下:
typedef struct _FILE_NOTIFY_INFORMATION {
DWORD NextEntryOffset;
DWORD Action;
DWORD FileNameLength;
WCHAR FileName[1];
} FILE_NOTIFY_INFORMATION, *PFILE_NOTIFY_INFORMATION;
可以看到,FileName是一个固定大小字符数组,他的大小是1;FileNameLength为第一个字符串的长度,从FileName首地址开始的FileNameLength个字符都属于第一个字符串;
NextEntryOffset为偏移量,从FileName首地址开始,偏移NextEntryOffset后,直到其有效长度内,提取出来就可以得到第二个字符串。
在上一章是这样使用的:
char notify[1024]; memset(notify, 0, sizeof(notify)); FILE_NOTIFY_INFORMATION *pNotification=(FILE_NOTIFY_INFORMATION *)notify;
也就是说对pNotification对象进行了填充,填充后的长度为1024字节,明显大于其原有长度,类似这种就是柔性数组。
pNotification是以指针的方式,将一段已经分配好的内存强制转换成FILE_NOTIFY_INFORMATION *格式,由于最后一个成员FileName的定义是字符数组,而字符数组的规矩是遇到零字符结束,所以只要FileName[0]和后面紧跟的字符不是非零字符,他的引用就不会结束,直到遇到零字符。
而ReadDirectoryChangesW 是一个 "W"例程,它使用的是Unicode。这个例程没有 ANSI 版本。因此,数据缓冲区自然也是Unicode。字符串不是 NULL 结尾的。
所以FileName的引用大小最大可以达到1024 - 3 * sizeof(DWORD)的大小。
获取pNotification的第一个字符串的方法如下:
CString szFileName(pNotification->FileName, pNotification->FileNameLength / sizeof(wchar_t));
获取第二个字符串的方法如下:
TCHAR newName[1024]={0};
ZeroMemory(newName, sizeof(newName));
int length = sizeof(notify) - pNotification->NextEntryOffset;
CopyMemory(newName, pNotification->FileName + pNotification->NextEntryOffset / sizeof(wchar_t), length);
以上都是我个人的理解,如有错误,欢迎指出。
浙公网安备 33010602011771号