文件夹监视及文件删除的简易方法
这几天学习了一些关于文件的操作,在这里做个总结。 我想实现这样的功能:当特定的文件夹Pic当检测到有文件(保证传进来的是图片)进来时,得到该文件的绝对路径,并把它传入void MoveControl(char *path); 处理,然后删除该图片文件。 在MFC中,如果想监视一个文件夹,以此了解在该文件夹中是否有文件加入或删除、重命名等操作,需要开一个子线程,把代码写在里面并用while(true)嵌套。 监视文件夹的API,我知道有两个——ReadDirectoryChangesW 和 FindFirstChangeNotification。觉得ReadDirectoryChangesW复杂就用FindFirstChangeNotification来写了。
首先调用FindFirstChangeNotification来告诉系统,我们的程序对于文件系统的变化消息感兴趣,此函数返回一个句柄,可以将它用于WaitForSingleObject或者WaitForMultipleObject的一些线程同步函数,一旦事件变成了有信号,便可得知文件系统有了变化,就可以漫游目录来得到新的信息。当这些处理完成后,再调用FindNextChangeNotification即可。 The FindNextChangeNotification function requests that the operating system signal a change notification handle the next time it detects an appropriate change.
UINT ThreadFunc(LPVOID lpParam) { DWORD dwWaitStatus; HANDLE dwChangeHandle; dwChangeHandle = FindFirstChangeNotification( TEXT("Pic"), // directory to watch 这里用的是相对路径 FALSE, // do not watch the subtree FILE_NOTIFY_CHANGE_FILE_NAME); // watch file name changes if (dwChangeHandle == INVALID_HANDLE_VALUE) ExitProcess(GetLastError()); while (TRUE) { // Wait for notification. dwWaitStatus=WaitForSingleObject(dwChangeHandle ,-1); //通知返回 switch (dwWaitStatus) { case WAIT_OBJECT_0: //file name changes if ( FindNextChangeNotification(dwChangeHandle) == FALSE ) ExitProcess(GetLastError()); // TODO: 在此添加额外的代码 break; default: break; } } return 0; }
在利用unicode编程时候,常常要涉及几种字符类型的转化,此时要用到 WideCharToMultiByte 或者 MultiByteToWideChar ,也可能在一些字符串前写TEXT(),这里就不多说了。
在MFC中,有一个CFileFind的类,用它可以很方便的获取某个文件夹中的所有文件的名字。
CString getFileName() { CFileFind file; CString fileName; BOOL isFind = file.FindFile(TEXT("Pic//*.*")); //相对路径,在Pic中找所有文件的文件名 while ( isFind ) { isFind = file.FindNextFile(); fileName = file.GetFileName();//可以得到找到的文件名 } file.Close(); return fileName; }
删除文件用CFile中的静态函数即可完成:
void DeletePic(char *path) { DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, path, -1, NULL, 0); wchar_t *pFileName; pFileName = new wchar_t[dwNum]; if(!pFileName) { delete []pFileName; } MultiByteToWideChar (CP_ACP, 0, path, -1, pFileName, dwNum); try { CFile::Remove(pFileName); } catch (CFileException* pEx) { #ifdef _DEBUG afxDump << "File " << pFileName << " cannot be removed/n"; #endif pEx->Delete(); } }
程序写完后,刚开始运行几次结果很理想。但是随后发现有时候往Pic里拖入图片程序没有反应。暂时想不明白是什么原因,我估计是线程函数的优先级过低。