遍历/删除windows文件和获取系统盘符

c++

Posted by YiMiTuMi on April 19, 2019

遍历文件

遍历当前路径下的所有文件并打印。

#include "stdafx.h"
#include <Windows.h>
#include <string>
#include <iostream>

using namespace std;

void FindFileWstr(const wstring filePath)
{
	HANDLE handlePath = NULL;

	do 
	{
		wstring findPath = L"";
		findPath.assign(filePath);
		findPath.append(L"\\*.*");
		wstring FindFilePath = L"";
		WIN32_FIND_DATAW wfd;
		handlePath = FindFirstFileW(findPath.c_str(), &wfd);

		if (handlePath == INVALID_HANDLE_VALUE)
		{
			break;
		}

		do 
		{
			if (lstrcmpW(wfd.cFileName, L".") == 0 || lstrcmpW(wfd.cFileName, L"..") == 0)
			{
				continue;
			}

			FindFilePath.assign(filePath);
			FindFilePath.append(L"\\");
			FindFilePath.append(wfd.cFileName);

			if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //判断是否是文件夹
			{
				wcout << FindFilePath << endl;
				FindFileWstr(FindFilePath);
			}
			else
			{
				wcout << FindFilePath << endl;
			}


		} while (FindNextFileW(handlePath, &wfd));


	} while (FALSE);

	if (handlePath != NULL)
	{
		FindClose(handlePath);
	}

}


int _tmain(int argc, _TCHAR* argv[])
{
	setlocale(LC_ALL, "chs");
	FindFileWstr(L"E:\\");
	getchar();
	return 0;
}

遍历删除文件夹和文件夹内的子项

由于c++函数和windows的API函数中没能用来删除文件夹和文件里内容的函数,windows可以通过dos命令:rd/s/q + 文件路径 来进行删除,但是通过函数调用命令行时很麻烦,所以在这写了一下通过windows的API函数进行删除文件夹及其子项。

void DeleteFileWstr(const wstring filePath)
{
    HANDLE handlePath = NULL;
    do 
    {
        wstring findPath = L"";
        findPath.assign(filePath);
        findPath.append(L"\\*.*");
        wstring deleteFilePath = L"";
        WIN32_FIND_DATAW wfd;
        handlePath = FindFirstFileW(findPath.c_str(), &wfd);

        if (handlePath == INVALID_HANDLE_VALUE)
        {
            break;
        }

        do 
        {
            if (lstrcmpW(wfd.cFileName, L".") == 0 || lstrcmpW(wfd.cFileName, L"..") == 0)
            {
                continue;
            }

            deleteFilePath.assign(filePath);
            deleteFilePath.append(L"\\");
            deleteFilePath.append(wfd.cFileName);
            wcout << wfd.cFileName << endl;

            if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //判断是否是文件夹
            {
                DeleteFileWstr(deleteFilePath);
            }
            else
            {
                DeleteFileW(deleteFilePath.c_str());
            }
        } while (FindNextFileW(handlePath, &wfd));


    } while (FALSE);

    if (handlePath != NULL)
    {
        FindClose(handlePath);
    }
    RemoveDirectoryW(filePath.c_str());//删除文件夹
}

int main()
{
    DeleteFileWstr(L"C:\\Program Files (x86)\\Tencent\\QQMusic");
    getchar();
    return 0;
}

获取系统盘符

vector<wstring> VecDrive;

//获取盘符
TCHAR LogicalDrives[MAX_PATH] = { 0 };
int nLen = GetLogicalDriveStringsW(MAX_PATH-1, LogicalDrives);
int i = 0;

do 
{
    TCHAR wcharDrives[MAX_PATH];
    wstring wstrDrive;
    wmemcpy(wcharDrives, LogicalDrives + i, 4);

    wstrDrive = wcharDrives;
    
    //判断当前磁盘类型
    int nType = GetDriveTypeW(wstrDrive.c_str());

    if (nType == DRIVE_FIXED) //硬盘
    {
	VecDrive.push_back(wstrDrive);
    }
	
    if (nType == DRIVE_REMOVABLE) //移动硬盘
    {
	VecDrive.push_back(wstrDrive);
    }
    
        i += 4;

} while (i<nLen);

vector<wstring>::iterator iter = VecDrive.begin();
for (;iter != VecDrive.end(); iter++)
{
    wcout << *iter << endl;
}

全盘遍历–一个盘一个线程

锁: std::_Mutex g_mutex;

main:

	vector<wstring> VecDrive; //保存盘符
	vector<wstring>::iterator iter = VecDrive.begin();
	HANDLE hSendServer = NULL;
			
	for (;iter != VecDrive.end(); iter++, iThread++)
	{	
		LPWSTR wstrDrive = (LPWSTR)(*iter).c_str();
		hFileFind = (HANDLE)_beginthreadex(NULL, 0, FileBackUpTaskThreadNew, wstrDrive, 0, NULL);
	}

线程:

	unsigned int __stdcall FileBackUpTaskThreadNew(void* pParam)
	{
		LPWSTR iter = (LPWSTR)pParam;
		FindFileWstr(iter);
	
		return 0;
	}

	void FindFileWstr(const wstring filePath)
	{
		HANDLE handlePath = NULL;
	
		do 
		{
			wstring findPath = L"";
			findPath.assign(filePath);
			findPath.append(L"\\*.*");
			wstring FindFilePath = L"";
			WIN32_FIND_DATAW wfd;
			handlePath = FindFirstFileW(findPath.c_str(), &wfd);
	
			if (handlePath == INVALID_HANDLE_VALUE)
			{
				break;
			}
	
			do 
			{
				if (lstrcmpW(wfd.cFileName, L".") == 0 || lstrcmpW(wfd.cFileName, L"..") == 0)
				{
					continue;
				}
			
				FindFilePath.assign(filePath);
				FindFilePath.append(L"\\");
				FindFilePath.append(wfd.cFileName);
				
				//判断路径是否使用
				wstring wstrwindows = L"C:\\Windows";
				wstring wstrPF = L"C:\\Program Files";
				wstring wstrPFX= L"C:\\Program Files (x86)";
	
				if (lstrcmpW(FindFilePath.c_str(), wstrwindows.c_str()) == 0 || 
					lstrcmpW(FindFilePath.c_str(), wstrPF.c_str()) == 0 || 
					lstrcmpW(FindFilePath.c_str(), wstrPFX.c_str()) == 0
					)
				{
					continue;
				}
	
				if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //判断是否是文件夹
				{
					g_mutex._Lock();
					wcout << L"文件夹:" << FindFilePath << endl;
					g_mutex._Unlock();
					FindFileWstr(FindFilePath);
				}
				else
				{
					g_mutex._Lock();
					wcout << L"文件:" << FindFilePath << endl;
					g_mutex._Unlock();
				}
			} while (FindNextFileW(handlePath, &wfd));
	
	
		} while (FALSE);
	
		if (handlePath != NULL)
		{
			FindClose(handlePath);
		}
	
	}

全盘遍历–每个文件夹起一个线程

锁: std::_Mutex g_mutex;

main: vector VecDrive; //保存盘符 vector::iterator iter = VecDrive.begin(); HANDLE hSendServer = NULL;

		for (;iter != VecDrive.end(); iter++, iThread++)
		{	
			LPWSTR wstrDrive = (LPWSTR)(*iter).c_str();
			hFileFind = (HANDLE)_beginthreadex(NULL, 0, FileBackUpTaskThread, wstrDrive, 0, NULL);
		}

线程:

	unsigned int __stdcall FileBackUpTaskThread(void* pParam)
	{
		HANDLE handlePath = NULL;
	
		do 
		{
			g_mutex1._Lock();
			//EnterCriticalSection(&my_winsec);
			
			LPWSTR iter = (LPWSTR)pParam;
			wstring filePath = iter;
			wstring findPath;
			findPath.assign(filePath);
			findPath.append(L"\\*.*");
			wstring FindFilePath;
			
			//LeaveCriticalSection(&my_winsec);
	
			WIN32_FIND_DATAW wfd;
			handlePath = FindFirstFileW(findPath.c_str(), &wfd);
			
			g_mutex1._Unlock();
	
			if (handlePath == INVALID_HANDLE_VALUE)
			{
				break;
			}
	
			do 
			{
				if (lstrcmpW(wfd.cFileName, L".") == 0 || lstrcmpW(wfd.cFileName, L"..") == 0)
				{
					continue;
				}
				
				//EnterCriticalSection(&my_winsec1);
				
				g_mutex._Lock();
				FindFilePath.assign(filePath);
				FindFilePath.append(L"\\");
				FindFilePath.append(wfd.cFileName);
				wcout << L"数据:" << FindFilePath << endl;
				g_mutex._Unlock();
	
	
				//判断路径是否使用
				wstring wstrwindows = L"C:\\Windows";
				wstring wstrPF = L"C:\\Program Files";
				wstring wstrPFX= L"C:\\Program Files (x86)";
	
				if (lstrcmpW(FindFilePath.c_str(), wstrwindows.c_str()) == 0 || 
					lstrcmpW(FindFilePath.c_str(), wstrPF.c_str()) == 0 || 
					lstrcmpW(FindFilePath.c_str(), wstrPFX.c_str()) == 0
					)
				{
					continue;
				}
	
				if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //判断是否是文件夹
				{
					
					HANDLE hFileFind = NULL;
	
					hFileFind = (HANDLE)_beginthreadex(NULL, 0, FileBackUpTaskThread, (LPWSTR)FindFilePath.c_str(), 0, NULL);
	
					if (hFileFind != NULL)
					{
						CloseHandle(hFileFind);
						hFileFind = NULL;
					}
	
				}
	
			} while (FindNextFileW(handlePath, &wfd));
	
	
		} while (FALSE);
	
		if (handlePath != NULL)
		{
			FindClose(handlePath);
		}
	
		return 0;   
	}

全盘扫描–多开一个线程用来输出数据

锁: std::_Mutex g_mutex;

全局变量:

	list<wstring> listFilePath;
	int iThread = 0;
	HANDLE hFileFind[MAX_PATH] = { 0 };

main: vector VecDrive; //保存盘符 vector::iterator iter = VecDrive.begin(); HANDLE hSendServer = NULL; int iLetterCount = VecDrive.size();

	for (;iter != VecDrive.end(); iter++, iThread++)
	{	
		LPWSTR wstrDrive = (LPWSTR)(*iter).c_str();
		hFileFind[iThread] = (HANDLE)_beginthreadex(NULL, 0, FileBackUpTaskThreadNew, wstrDrive, 0, NULL);
	}
	
	//可以等待多个线程结束
	DWORD dwWait = WaitForMultipleObjects(iLetterCount, hFileFindThread, TRUE, INFINITE);

	while (iLetterCount != 0)
	{
		if (hFileFindThread[iLetterCount - 1] != INVALID_HANDLE_VALUE)
		{
			CloseHandle(hFileFindThread[iLetterCount - 1]);
			hFileFindThread[iLetterCount - 1] = INVALID_HANDLE_VALUE;
		}

		iLetterCount--;
	}
	
	
	hSendServer = (HANDLE)_beginthreadex(NULL, 0, FileBackUpSendServer, NULL, 0, NULL);
	
	if (hSendServer != NULL)
	{
		CloseHandle(hSendServer);
		hSendServer = NULL;
	}

全盘遍历线程函数:

	unsigned int __stdcall FileBackUpTaskThreadNew(void* pParam)
	{
		LPWSTR iter = (LPWSTR)pParam;
		FindFileWstr(iter);
	
		return 0;
	}

	void FindFileWstr(const wstring filePath)
	{
		HANDLE handlePath = NULL;
	
		do 
		{
			wstring findPath = L"";
			findPath.assign(filePath);
			findPath.append(L"\\*.*");
			wstring FindFilePath = L"";
			WIN32_FIND_DATAW wfd;
			handlePath = FindFirstFileW(findPath.c_str(), &wfd);
	
			if (handlePath == INVALID_HANDLE_VALUE)
			{
				break;
			}
	
			do 
			{
				if (lstrcmpW(wfd.cFileName, L".") == 0 || lstrcmpW(wfd.cFileName, L"..") == 0)
				{
					continue;
				}
			
				FindFilePath.assign(filePath);
				FindFilePath.append(L"\\");
				FindFilePath.append(wfd.cFileName);
	
				g_mutex._Lock();
				listFilePath.push_front(FindFilePath);
				//wcout << L"文件夹:" << FindFilePath << endl;
				g_mutex._Unlock();
				
				//判断路径是否使用
				wstring wstrwindows = L"C:\\Windows";
				wstring wstrPF = L"C:\\Program Files";
				wstring wstrPFX= L"C:\\Program Files (x86)";
	
				if (lstrcmpW(FindFilePath.c_str(), wstrwindows.c_str()) == 0 || 
					lstrcmpW(FindFilePath.c_str(), wstrPF.c_str()) == 0 || 
					lstrcmpW(FindFilePath.c_str(), wstrPFX.c_str()) == 0
					)
				{
					continue;
				}
	
				if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //判断是否是文件夹
				{
					FindFileWstr(FindFilePath);
				}
				
			} while (FindNextFileW(handlePath, &wfd));
	
	
		} while (FALSE);
	
		if (handlePath != NULL)
		{
			FindClose(handlePath);
		}
	
	}

用来输出的线程函数:

	unsigned int __stdcall FileBackUpSendServer(void* pParam)
	{
		while (1)
		{
			BOOL bExitCode = FALSE;
			g_mutex._Lock();
			list<wstring>::iterator iter = listFilePath.begin();
	
			if (iter != listFilePath.end())
			{
				wcout << L"数据:" << *iter << endl;
				listFilePath.erase(iter);
			}
			g_mutex._Unlock();
			
			int i = iThread;
			for (;i >= 0 && !bExitCode; i--)
			{
				DWORD iExitCode = 0;
				GetExitCodeThread(hFileFind[i], &iExitCode);
				if (iExitCode == STILL_ACTIVE)
				{
					bExitCode = TRUE;
					break;
				}
			}
		
			if (!bExitCode && listFilePath.empty())
			{
				break;
			}
		}
		
		for (;iThread != 0; iThread--)
		{
			if (hFileFind[iThread] == NULL)
			{
				CloseHandle(hFileFind[iThread]);
			}
		}
		
		wcout << L"------------End------------------" << endl;
	
		return 0;
	}

罂粟花 – 令人窒息的美