Windows 实战项目 001 文件扫描器 (01)
Posted ☆﹎夜﹎☆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 9 //递归的方法继续搜索 10 unsigned g_nFindedFileNum = 0; 11 unsigned g_nSearchFileNum = 0; 12 unsigned g_nSearchDirNum = 0; 13 14 std::wstring MakeStandardDirName(const std::wstring &wstrDirname) 15 { 16 if (wstrDirname.back() != \'\\\\\') 17 return wstrDirname + L"\\\\"; 18 return wstrDirname; 19 } 20 void MyFileFind(std::wstring &wstrBeginDirName, std::wstring &wstrSearch, std::wstring wstrFile = L"*.*") 21 { 22 23 WIN32_FIND_DATAW findFile = { 0 }; 24 25 HANDLE hFileFind = FindFirstFileW((MakeStandardDirName(wstrBeginDirName)+wstrFile).c_str(), &findFile); 26 27 do 28 { 29 if (wcscmp(findFile.cFileName, L".") == 0) 30 continue; 31 if (wcscmp(findFile.cFileName, L"..") == 0) 32 continue; 33 if (findFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 34 //printf("Dir \\t\\t\\t %ls \\r\\n", findFile.cFileName); 35 { 36 MyFileFind(MakeStandardDirName(wstrBeginDirName) + findFile.cFileName, wstrSearch); 37 g_nSearchDirNum++; 38 } 39 else 40 //printf("File \\t\\t\\t %ls \\r\\n", findFile.cFileName); 41 { 42 if (wcsstr(findFile.cFileName, wstrSearch.c_str()) != nullptr) 43 { 44 printf("Searched File In:\\t %ls \\r\\n",(MakeStandardDirName(wstrBeginDirName)+findFile.cFileName).c_str()); 45 g_nFindedFileNum++; 46 } 47 g_nSearchFileNum++; 48 } 49 } while (FindNextFileW(hFileFind, &findFile)); 50 51 // return g_nFindedFileNum; 52 } 53 54 int main() 55 { 56 system("color b"); 57 std::wstring wstrBeginDirName = L"C:\\\\"; 58 std::wstring wstrSearchName = L"ntdll"; 59 60 DWORD dwBegin = GetTickCount(); 61 MyFileFind(wstrBeginDirName, wstrSearchName); 62 63 DWORD dwTime = GetTickCount() - dwBegin; 64 printf("耗费时间:%d(秒)\\r\\n合计找到:%d个文件\\r\\n共遍历过%d个文件夹和%d个文件!\\r\\n", 65 dwTime/1000, g_nFindedFileNum, g_nSearchDirNum, g_nSearchFileNum); 66 67 system("pause"); 68 return 0; 69 }
重点:
if (wcsstr(findFile.cFileName, wstrSearch.c_str()) != nullptr)
比较字符串 是否存在,文件名称是否匹配
递归的实现方法
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 }
多线程实现发放
// Everything.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <stdio.h> #include <string> #include <process.h> #include <vector> #include <windows.h> //递归的方法继续搜索 //unsigned g_nFindedFileNum = 0; //unsigned g_nSearchFileNum = 0; //unsigned g_nSearchDirNum = 0; std::wstring MakeStandardDirName(const std::wstring &wstrDirname) { if (wstrDirname.back() != \'\\\\\') return wstrDirname + L"\\\\"; return wstrDirname; } //void MyFileFind(std::wstring &wstrBeginDirName, std::wstring &wstrSearch, std::wstring wstrFile = L"*.*") //{ // // WIN32_FIND_DATAW findFile = { 0 }; // // HANDLE hFileFind = FindFirstFileW((MakeStandardDirName(wstrBeginDirName) + wstrFile).c_str(), &findFile); // // do // { // if (wcscmp(findFile.cFileName, L".") == 0) // continue; // if (wcscmp(findFile.cFileName, L"..") == 0) // continue; // if (findFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // //printf("Dir \\t\\t\\t %ls \\r\\n", findFile.cFileName); // { // MyFileFind(MakeStandardDirName(wstrBeginDirName) + findFile.cFileName, wstrSearch); // g_nSearchDirNum++; // } // else // //printf("File \\t\\t\\t %ls \\r\\n", findFile.cFileName); // { // if (wcsstr(findFile.cFileName, wstrSearch.c_str()) != nullptr) // { // printf("Searched File In:\\t %ls \\r\\n", (MakeStandardDirName(wstrBeginDirName) + findFile.cFileName).c_str()); // g_nFindedFileNum++; // } // g_nSearchFileNum++; // } // } while (FindNextFileW(hFileFind, &findFile)); // return g_nFindedFileNum; //} HANDLE g_hExitEvent; std::vector<HANDLE> g_hThreads; CRITICAL_SECTION g_cs; long g_lFindedFileNum = 0; long g_lSearchFileNum = 0; long g_lSearchDirNum = 0; long g_lWorkThreadNum = 0; struct ThreadData { std::wstring wstrDirName; std::wstring wstrSearch; std::wstring wstrFile; }; unsigned __stdcall ThreadFileFind(void *lParam) { InterlockedAdd(&g_lWorkThreadNum, 1); ThreadData *pData = (ThreadData*)lParam; WIN32_FIND_DATAW fileFind = { 0 }; HANDLE hFileFind = FindFirstFileW( (MakeStandardDirName(pData->wstrDirName) + pData->wstrFile).c_str(), &fileFind); do { if (wcscmp(fileFind.cFileName, L".") == 0) continue; if (wcscmp(fileFind.cFileName, L"..") == 0) continue; if (fileFind.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { ThreadData *pTempData = new ThreadData; pTempData->wstrDirName = MakeStandardDirName(pData->wstrDirName) + fileFind.cFileName; pTempData->wstrFile = pData->wstrFile; pTempData->wstrSearch = pData->wstrSearch; //上锁 EnterCriticalSection(&g_cs); CloseHandle((HANDLE)_beginthreadex(nullptr, 0, ThreadFileFind, pTempData, 0, nullptr)); //g_hThreads.push_back((HANDLE)_beginthreadex(nullptr, 0, ThreadFileFind, pTempData, 0, nullptr)); LeaveCriticalSection(&g_cs); //原子操作 InterlockedAdd(&g_lSearchDirNum, 1); } else { if(wcsstr(fileFind.cFileName,pData->wstrSearch.c_str()) != nullptr) { printf("Searched File In:\\t %ls \\r\\n", (MakeStandardDirName(pData->wstrDirName) + fileFind.cFileName).c_str()); InterlockedAdd(&g_lFindedFileNum, 1); } InterlockedAdd(&g_lSearchFileNum, 1); } } while (FindNextFileW(hFileFind,&fileFind)); delete pData; InterlockedAdd(&g_lWorkThreadNum, -1); if (g_lWorkThreadNum == 0) SetEvent(g_hExitEvent); return 0; } int main() { //初始化锁 InitializeCriticalSection(&g_cs); g_hExitEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); ThreadData *pTempData = new ThreadData; pTempData->wstrDirName = L"C:"; pTempData->wstrFile = L"*.*"; pTempData->wstrSearch = L"ntdll"; DWORD dwBegin = GetTickCount(); CloseHandle((HANDLE)_beginthreadex(nullptr, 0, ThreadFileFind, pTempData, 0, nullptr)); //g_hThreads.push_back((HANDLE)_beginthreadex(nullptr, 0, ThreadFileFind, pTempData, 0, nullptr)); //WaitForMultipleObjects(g_hThreads.size(), g_hThreads.data(), TRUE, INFINITE); WaitForSingleObject(g_hExitEvent, INFINITE); DWORD dwTime = GetTickCount() - dwBegin; //关闭句柄 for (auto g_h_thread : g_hThreads) { CloseHandle(g_h_thread); } DeleteCriticalSection(&g_cs); printf("耗费时间:%d(秒)\\r\\n合计找到:%d个文件\\r\\n共遍历过%d个文件夹和%d个文件!\\r\\n", dwTime / 1000, g_lFindedFileNum, g_lSearchDirNum, g_lSearchFileNum); //什么时候搜索完成 //system("color b"); //std::wstring wstrBeginDirName = L"C:\\\\"; //std::wstring wstrSearchName = L"ntdll"; //DWORD dwBegin = GetTickCount(); //MyFileFind(wstrBeginDirName, wstrSearchName); //DWORD dwTime = GetTickCount() - dwBegin; //printf("耗费时间:%d(秒)\\r\\n合计找到:%d个文件\\r\\n共遍历过%d个文件夹和%d个文件!\\r\\n", // dwTime / 1000, g_nFindedFileNum, g_nSearchDirNum, g_nSearchFileNum); system("pause"); return 0; }
以上是关于Windows 实战项目 001 文件扫描器 (01)的主要内容,如果未能解决你的问题,请参考以下文章
便宜出课!C++视频windows界面UI编程MFCGDI自绘项目实战网络编程教程我有原版