Windows 实战项目 001 文件扫描器 (01)
# Windows 实战项目 001 文件扫描器 (01)
- 主要实现功能
- 搜索系统目录文件
- 找到文件并打印输出
- 主要使用到的函数
- FindFirstFile
函数原型:
1 HANDLE WINAPI FindFirstFile( 2 _In_ LPCTSTR lpFileName, 3 _Out_ LPWIN32_FIND_DATA lpFindFileData 4 );
参数1 lpFileName
搜索的文件名
c:\Windows\*.* //在c:\Windows目录中查找所有文件 c:\Windows\System32\*.dll //在c:\Windows\System32目录中查找所有dll文件 c:\Windows\System.ini; //在c:\Windows目录中查找System.ini文件 c:\Windows\a???.* //在c:\Windows目录中查找所有以a开头的文件名长度.为4个字符的文件 Test.dat //在当前目录查找Test.dat文件 *.* //在当前目录查找所有文件
参数2 lpFindFileData
搜索到文件数据 输出信息的 结构体
返回值
返回成功
如果函数返回成功,则返回值是后续调用 FindNextFile 或者 FindClose 时使用的搜索句柄,
lpFindFileData 参数包含有关找到的第一个文件或目录的信息
返回失败
如果函数失败或无法从lpFileName参数中的搜索字符串中找到文件,则返回为 INVALID_HANDLE_VALUE
并且lpFindFileData的内容不确定的,用 GetLastError 获取操作代码
如果函数失败,因为找不到匹配文件,GetLastError函数返回 ERROR_FILE_NOT_FOUND;
- FindNextFile
函数原型
1 HANDLE WINAPI FindFirstFile( 2 _In_ LPCTSTR lpFileName, 3 _Out_ LPWIN32_FIND_DATA lpFindFileData 4 );
参数1:lpFileName
搜索到的文件名字,或者目录名称。不能为空
参数2 lpFindFileData
搜索到文件数据 输出信息的 结构体
返回值
返回成功
如果函数返回成功,则返回值是后续调用 FindNextFile 或者 FindClose 时使用的搜索句柄,
lpFindFileData 参数包含有关找到的第一个文件或目录的信息
返回失败
如果函数失败或无法从lpFileName参数中的搜索字符串中找到文件,则返回为 INVALID_HANDLE_VALUE
并且lpFindFileData的内容不确定的,用 GetLastError 获取操作代码
如果函数失败,因为找不到匹配文件,GetLastError函数返回 ERROR_FILE_NOT_FOUND;
文件属性常量
文件属性是文件系统在磁盘上存储的元数据值,由系统使用,可通过各种文件I / O API向开发人员提供。有关相关API和主题的列表,请参阅另请参阅部分。
简单使用代码
1 #include <stdio.h> 2 #include <windows.h> 3 #include <string> 4 5 int main() 6 { 7 std::wstring wstrBeginDirName = L"C:\\*.*"; 8 std::wstring wstrSearchName = L"ntdll"; 9 10 WIN32_FIND_DATAW findFile = { 0 }; 11 12 HANDLE hFileFind = FindFirstFileW(wstrBeginDirName.c_str(), &findFile); 13 14 do 15 { 16 printf("File name: %ls \r\n", findFile.cFileName); 17 } while (FindNextFileW(hFileFind, &findFile)); 18 19 system("pause"); 20 return 0; 21 }
判断是否是文件夹
1 #include <stdio.h> 2 #include <windows.h> 3 #include <string> 4 5 int main() 6 { 7 system("color b"); 8 std::wstring wstrBeginDirName = L"C:\\*.*"; 9 std::wstring wstrSearchName = L"ntdll"; 10 11 WIN32_FIND_DATAW findFile = { 0 }; 12 13 HANDLE hFileFind = FindFirstFileW(wstrBeginDirName.c_str(), &findFile); 14 15 do 16 { 17 if (findFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 18 printf("Dir \t\t\t %ls \r\n", findFile.cFileName); 19 else 20 printf("File \t\t\t %ls \r\n", findFile.cFileName); 21 } while (FindNextFileW(hFileFind, &findFile)); 22 23 system("pause"); 24 return 0; 25 }
重点:
findFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
findFile.dwFileAttributes 一个多值的 不能使用 ==
FILE_ATTRIBUTE_DIRECTORY 常量 16(0x10) 进行逻辑与运算
递归实现方法
1 // Everything.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <stdio.h> 6 #include <windows.h> 7 #include <string> 8 #include <process.h> 9 10 //递归的方法继续搜索 11 unsigned g_nFindedFileNum = 0; 12 unsigned g_nSearchFileNum = 0; 13 unsigned g_nSearchDirNum = 0; 14 15 std::wstring MakeStandardDirName(const std::wstring &wstrDirname) 16 { 17 if (wstrDirname.back() != '\\') 18 return wstrDirname + L"\\"; 19 return wstrDirname; 20 } 21 void MyFileFind(std::wstring &wstrBeginDirName, std::wstring &wstrSearch, std::wstring wstrFile = L"*.*") 22 { 23 24 WIN32_FIND_DATAW findFile = { 0 }; 25 26 HANDLE hFileFind = FindFirstFileW((MakeStandardDirName(wstrBeginDirName)+wstrFile).c_str(), &findFile); 27 28 do 29 { 30 if (wcscmp(findFile.cFileName, L".") == 0) 31 continue; 32 if (wcscmp(findFile.cFileName, L"..") == 0) 33 continue; 34 if (findFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 35 //printf("Dir \t\t\t %ls \r\n", findFile.cFileName); 36 { 37 MyFileFind(MakeStandardDirName(wstrBeginDirName) + findFile.cFileName, wstrSearch); 38 g_nSearchDirNum++; 39 } 40 else 41 //printf("File \t\t\t %ls \r\n", findFile.cFileName); 42 { 43 if (wcsstr(findFile.cFileName, wstrSearch.c_str()) != nullptr) 44 { 45 printf("Searched File In:\t %ls \r\n",(MakeStandardDirName(wstrBeginDirName)+findFile.cFileName).c_str()); 46 g_nFindedFileNum++; 47 } 48 g_nSearchFileNum++; 49 } 50 } while (FindNextFileW(hFileFind, &findFile)); 51 52 // return g_nFindedFileNum; 53 } 54 55 int main() 56 { 57 system("color b"); 58 std::wstring wstrBeginDirName = L"C:\\"; 59 std::wstring wstrSearchName = L"ntdll"; 60 61 DWORD dwBegin = GetTickCount(); 62 MyFileFind(wstrBeginDirName, wstrSearchName); 63 64 DWORD dwTime = GetTickCount() - dwBegin; 65 printf("耗费时间:%d(秒)\r\n合计找到:%d个文件\r\n共遍历过%d个文件夹和%d个文件!\r\n", 66 dwTime/1000, g_nFindedFileNum, g_nSearchDirNum, g_nSearchFileNum); 67 68 system("pause"); 69 return 0; 70 }
多线程实现方法
1 // Everything.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <stdio.h> 6 #include <string> 7 #include <process.h> 8 #include <vector> 9 #include <windows.h> 10 11 //递归的方法继续搜索 12 //unsigned g_nFindedFileNum = 0; 13 //unsigned g_nSearchFileNum = 0; 14 //unsigned g_nSearchDirNum = 0; 15 16 std::wstring MakeStandardDirName(const std::wstring &wstrDirname) 17 { 18 if (wstrDirname.back() != '\\') 19 return wstrDirname + L"\\"; 20 return wstrDirname; 21 } 22 //void MyFileFind(std::wstring &wstrBeginDirName, std::wstring &wstrSearch, std::wstring wstrFile = L"*.*") 23 //{ 24 // 25 // WIN32_FIND_DATAW findFile = { 0 }; 26 // 27 // HANDLE hFileFind = FindFirstFileW((MakeStandardDirName(wstrBeginDirName) + wstrFile).c_str(), &findFile); 28 // 29 // do 30 // { 31 // if (wcscmp(findFile.cFileName, L".") == 0) 32 // continue; 33 // if (wcscmp(findFile.cFileName, L"..") == 0) 34 // continue; 35 // if (findFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 36 // //printf("Dir \t\t\t %ls \r\n", findFile.cFileName); 37 // { 38 // MyFileFind(MakeStandardDirName(wstrBeginDirName) + findFile.cFileName, wstrSearch); 39 // g_nSearchDirNum++; 40 // } 41 // else 42 // //printf("File \t\t\t %ls \r\n", findFile.cFileName); 43 // { 44 // if (wcsstr(findFile.cFileName, wstrSearch.c_str()) != nullptr) 45 // { 46 // printf("Searched File In:\t %ls \r\n", (MakeStandardDirName(wstrBeginDirName) + findFile.cFileName).c_str()); 47 // g_nFindedFileNum++; 48 // } 49 // g_nSearchFileNum++; 50 // } 51 // } while (FindNextFileW(hFileFind, &findFile)); 52 53 // return g_nFindedFileNum; 54 //} 55 56 HANDLE g_hExitEvent; 57 std::vector<HANDLE> g_hThreads; 58 59 CRITICAL_SECTION g_cs; 60 61 long g_lFindedFileNum = 0; 62 long g_lSearchFileNum = 0; 63 long g_lSearchDirNum = 0; 64 long g_lWorkThreadNum = 0; 65 66 struct ThreadData 67 { 68 std::wstring wstrDirName; 69 std::wstring wstrSearch; 70 std::wstring wstrFile; 71 }; 72 73 unsigned __stdcall ThreadFileFind(void *lParam) 74 { 75 InterlockedAdd(&g_lWorkThreadNum, 1); 76 77 ThreadData *pData = (ThreadData*)lParam; 78 79 WIN32_FIND_DATAW fileFind = { 0 }; 80 HANDLE hFileFind = FindFirstFileW( 81 (MakeStandardDirName(pData->wstrDirName) + pData->wstrFile).c_str(), &fileFind); 82 do 83 { 84 if (wcscmp(fileFind.cFileName, L".") == 0) 85 continue; 86 if (wcscmp(fileFind.cFileName, L"..") == 0) 87 continue; 88 if (fileFind.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 89 { 90 ThreadData *pTempData = new ThreadData; 91 pTempData->wstrDirName = MakeStandardDirName(pData->wstrDirName) + fileFind.cFileName; 92 pTempData->wstrFile = pData->wstrFile; 93 pTempData->wstrSearch = pData->wstrSearch; 94 95 //上锁 96 EnterCriticalSection(&g_cs); 97 98 CloseHandle((HANDLE)_beginthreadex(nullptr, 0, ThreadFileFind, pTempData, 0, nullptr)); 99 //g_hThreads.push_back((HANDLE)_beginthreadex(nullptr, 0, ThreadFileFind, pTempData, 0, nullptr)); 100 101 LeaveCriticalSection(&g_cs); 102 103 //原子操作 104 InterlockedAdd(&g_lSearchDirNum, 1); 105 } 106 else 107 { 108 if(wcsstr(fileFind.cFileName,pData->wstrSearch.c_str()) != nullptr) 109 { 110 printf("Searched File In:\t %ls \r\n", (MakeStandardDirName(pData->wstrDirName) + fileFind.cFileName).c_str()); 111 InterlockedAdd(&g_lFindedFileNum, 1); 112 } 113 InterlockedAdd(&g_lSearchFileNum, 1); 114 } 115 116 } while (FindNextFileW(hFileFind,&fileFind)); 117 delete pData; 118 119 InterlockedAdd(&g_lWorkThreadNum, -1); 120 if (g_lWorkThreadNum == 0) 121 SetEvent(g_hExitEvent); 122 return 0; 123 } 124 125 int main() 126 { 127 //初始化锁 128 InitializeCriticalSection(&g_cs); 129 130 g_hExitEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); 131 132 ThreadData *pTempData = new ThreadData; 133 pTempData->wstrDirName = L"C:"; 134 pTempData->wstrFile = L"*.*"; 135 pTempData->wstrSearch = L"ntdll"; 136 137 DWORD dwBegin = GetTickCount(); 138 CloseHandle((HANDLE)_beginthreadex(nullptr, 0, ThreadFileFind, pTempData, 0, nullptr)); 139 //g_hThreads.push_back((HANDLE)_beginthreadex(nullptr, 0, ThreadFileFind, pTempData, 0, nullptr)); 140 141 //WaitForMultipleObjects(g_hThreads.size(), g_hThreads.data(), TRUE, INFINITE); 142 143 WaitForSingleObject(g_hExitEvent, INFINITE); 144 145 DWORD dwTime = GetTickCount() - dwBegin; 146 147 //关闭句柄 148 for (auto g_h_thread : g_hThreads) 149 { 150 CloseHandle(g_h_thread); 151 } 152 153 DeleteCriticalSection(&g_cs); 154 155 156 printf("耗费时间:%d(秒)\r\n合计找到:%d个文件\r\n共遍历过%d个文件夹和%d个文件!\r\n", 157 dwTime / 1000, g_lFindedFileNum, g_lSearchDirNum, g_lSearchFileNum); 158 159 //什么时候搜索完成 160 161 //system("color b"); 162 //std::wstring wstrBeginDirName = L"C:\\"; 163 //std::wstring wstrSearchName = L"ntdll"; 164 165 //DWORD dwBegin = GetTickCount(); 166 //MyFileFind(wstrBeginDirName, wstrSearchName); 167 168 //DWORD dwTime = GetTickCount() - dwBegin; 169 //printf("耗费时间:%d(秒)\r\n合计找到:%d个文件\r\n共遍历过%d个文件夹和%d个文件!\r\n", 170 // dwTime / 1000, g_nFindedFileNum, g_nSearchDirNum, g_nSearchFileNum); 171 172 system("pause"); 173 return 0; 174 }