【Windows系统编程】01.文件与目录操作-笔记

本专栏从这篇文章开始做Windows系统编程的笔记,本章主要讲解:Windows文件操作(读写文件,删除文件,拷贝文件,移动文件等),目录操作(遍历目录,删除目录等)硬盘的一点小知识。
参考书:Windows核心编程

文件,内核对象

#include 
#include 

int main()
{
	//打开文件或I/O设备
	HANDLE hFile = CreateFile(L"E:\\Test A\\111.txt",   //文件名
		GENERIC_READ | GENERIC_WRITE,                   //打开方式
		NULL,                                           //共享模式,这里NULL是独占
		NULL,                                           //安全属性
		OPEN_ALWAYS,                                    //要对存在或不存在的文件或设备进行的操作
		FILE_ATTRIBUTE_NORMAL,                          //文件或设备属性
		NULL
	);

	//INVALID_HANDLE_VALUE宏是微软提出的专门用于判断句柄是否有效的宏
	if (hFile == INVALID_HANDLE_VALUE) {
		std::cout << "CreateFile Failed!" << std::endl;
	}

	//定义我们要写入文件的字符串
	CHAR* szBuffer[MAX_PATH] = { 0 };
	memcpy(szBuffer, "Hello Windows File!", sizeof("Hello Windows File!"));

	DWORD dwNumberOfBytesWritten = 0;
	BOOL bRet = WriteFile(
		hFile,                    //文件句柄
		szBuffer,                 //字符串地址
		sizeof("Hello Windows File!"),//写入文件大小
		&dwNumberOfBytesWritten,
		NULL
	);

	if (!bRet) {
		std::cout << "WriteFile Faild!" << std::endl;
	}

	CloseHandle(hFile);
	system("pause");
	return 0;
}

上述的是没有错误的操作流程

如果文件已经存在的话,就会出现错误

我们在开发过程中,如何定位错误?

监视->添加监视:err,hr

这样,如果出现错误,错误原因也就会显示了

或者,复制错误码,在工具:错误查找中,查找错误原因

或者:

std::cout<<GetLaseError()<<std::endl;
这样会直接打印出错误码
  • 读文件:

    #include 
    #include 
    
    int main()
    {
    	//打开文件或I/O设备
    	HANDLE hFile = CreateFile(L"E:\\Test A\\111.txt",   //文件名
    		GENERIC_READ | GENERIC_WRITE,                   //打开方式
    		NULL,                                           //共享模式,这里NULL是独占
    		NULL,                                           //安全属性
    		OPEN_ALWAYS,                                    //要对存在或不存在的文件或设备进行的操作
    		FILE_ATTRIBUTE_NORMAL,                          //文件或设备属性
    		NULL
    	);
    
    	//INVALID_HANDLE_VALUE宏是微软提出的专门用于判断句柄是否有效的宏
    	if (hFile == INVALID_HANDLE_VALUE) {
    		std::cout << "CreateFile Failed!" << std::endl;
    	}
    
    	//获取文件大小
    	LARGE_INTEGER lpFileSize;
    	/*
    	typedef union _LARGE_INTEGER {
    		struct {
    			DWORD LowPart;
    			LONG HighPart;
    		} DUMMYSTRUCTNAME;
    		struct {
    			DWORD LowPart;
    			LONG HighPart;
    		} u;
    		LONGLONG QuadPart;
    	} LARGE_INTEGER;
    	*/
    	if (!GetFileSizeEx(hFile, &lpFileSize
    		)) {
    		std::cout << "GetFileSize Failed!" << std::endl;
    		std::cout << "错误码:" << GetLastError() << std::endl;
    	}
    
    	//定义我们要读出文件的字符串
    	CHAR* szBuffer = new CHAR[lpFileSize.LowPart + 1];
    	memset(szBuffer, 0, lpFileSize.LowPart + 1);
    
    	DWORD lpNumberOfBytesRead;
    	BOOL bRet = ReadFile(hFile,
    		szBuffer,
    		lpFileSize.LowPart,
    		&lpNumberOfBytesRead,
    		NULL
    	);
    
    	if (bRet) {
    		std::cout << szBuffer << std::endl;
    	}
    	else {
    		std::cout << "ReadFile Faild!" << std::endl;
    	}
    
    	CloseHandle(hFile);
    	system("pause");
    	return 0;
    }
    
    
  • 移动文件:

    	//移动文件
    	if (MoveFile(L"E:\\Test A\\111.txt", L"E:\\Test B\\222.txt")) {
    		std::cout << "移动成功" << std::endl;
    	}
    	else {
    		std::cout << "移动失败!" << std::endl;
    	}
    
    	//删除文件
    	if (DeleteFile(L"E:\\Test B\\222.txt")) {
    		std::cout << "删除成功" << std::endl;
    	}
    	else {
    		std::cout << "删除失败!" << std::endl;
    	}
    
    	//拷贝文件
    	if (CopyFile(L"E:\\Test B\\222 - 副本.txt", L"E:\\Test A\\111.txt", TRUE)) {
    		std::cout << "移动成功" << std::endl;
    	}
    	else {
    		std::cout << "移动失败!" << std::endl;
    	}
    
    

目录

	//创建新目录:
	CreateDirectory(L"E:\\Test C", NULL);
	//删除目录(只能删除空目录):
	RemoveDirectory(L"E:\\Test C");

	//遍历文件目录:
	WIN32_FIND_DATAW FindFileData;
	HANDLE hFile = FindFirstFile(L"E:\\*", &FindFileData);

	if (hFile == INVALID_HANDLE_VALUE) {
		std::cout << "FindFirstFile Failed" << std::endl;
	}

	do {
		//判断是否为目录:
		if (FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) {
			std::cout << "(Directory)";
		}

		std::cout << FindFileData.cFileName << ":";
		
		//处理时间:
		SYSTEMTIME Systime;
		FileTimeToSystemTime(&FindFileData.ftCreationTime, &Systime);
		std::cout << Systime.wYear << "-" << Systime.wMonth << "-" << Systime.wDay << "-" << Systime.wHour << "-" << Systime.wMinute << std::endl;


	} while (FindNextFile(hFile, &FindFileData));

.:当前路径

…:上级路径

一般如果想要遍历C盘文件,需要手动提权,或者:

属性页-连接器-清单文件,UAC执行级别:设置高级

获取单个文件详细信息

#include 
#include 

int main(){
	//获取单个文件详细信息:
	HANDLE hFile = CreateFile(L"E:\\Test A\\111.txt", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPWN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	BY_HANDLE_FILE_INFORMATION bhFileInfo;
	GetFileInformationByHandle(hFile, &bhFileInfo);
  std::cout<<......<<std::endl;
  system("pause");
  return 0;
}

盘符

A-Z

Z之后,挂硬盘挂不上去

A,B盘是软盘

获取磁盘类型:

UINT uRet = GetDriveType("C:");

查询磁盘相关信息:

GetVolumeInformation()

获取磁盘大小:

GetDiskFreeSpace("D:\\",...)

硬盘(卷)GUIID:

char szvolume[MAX_PATH]={0};
HANDLE hVolume = FindFirstVolume(szVolume,MAX_PATH);
std::cout<<szVolume<<std::endl;
while(FindNextVolume(hVolume,szVolume,MAX_PATH)){
  std::cout<<szVolume<<std::endl;
}
FindVolumeClostd(hVolume);

作业

  1. 自己实现拷贝文件功能(CopyFile)
    BOOL MyCopyFile(LPCWSTR Src, LPCWSTR New,BOOL nFlag)
    {
    	HANDLE hSrcFile = NULL;
    	switch (nFlag) {
    	case FALSE: {
    		hSrcFile = CreateFile(Src, GENERIC_READ, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    		if (hSrcFile == INVALID_HANDLE_VALUE) {
    			std::cout << "CreateFile Failed" << std::endl;
    			return FALSE;
    		}
    	}
    	case TRUE: {
    		hSrcFile = CreateFile(Src, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    		if (hSrcFile == INVALID_HANDLE_VALUE) {
    			std::cout << "CreateFile Failed" << std::endl;
    			return FALSE;
    		}
    	}
    	}
    
    	LARGE_INTEGER lpFileSize;
    	if (!GetFileSizeEx(hSrcFile, &lpFileSize)) {
    		std::cout << "GetFileSize Failed" << std::endl;
    		std::cout << GetLastError() << std::endl;
    		return FALSE;
    	}
    
    	CHAR* szBuffer = new CHAR[lpFileSize.LowPart + 1];
    	if (szBuffer == nullptr) {
    		std::cout << "申请内存失败!" << std::endl;
    		return FALSE;
    	}
    	memset(szBuffer, 0, lpFileSize.LowPart + 1);
    
    	DWORD lpNumberOfBytesRead;
    	BOOL bRet = ReadFile(hSrcFile, szBuffer, lpFileSize.LowPart, &lpNumberOfBytesRead, NULL);
    	if (!bRet) {
    		std::cout << "ReadFile Failed!" << std::endl;
    		return FALSE;
    	}
    
    	HANDLE hNewFile = CreateFile(New, GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    	if (hNewFile == INVALID_HANDLE_VALUE) {
    		std::cout << "CreateFile Failed!" << std::endl;
    		return FALSE;
    	}
    
    	DWORD lpNumberOfBytesWritten;
    	bRet = WriteFile(hNewFile, szBuffer, lpFileSize.LowPart, &lpNumberOfBytesWritten, NULL);
    	if (!bRet) {
    		std::cout << "WriteFile Failed!" << std::endl;
    		return FALSE;
    	}
    
    	CloseHandle(hSrcFile);
    	CloseHandle(hNewFile);
    	delete(szBuffer);
    	return TRUE;
    }
    
  2. 自己实现移动文件(MoveFile)功能
    BOOL MyMoveFile(LPCWSTR Src, LPCWSTR New)
    {
    	HANDLE hSrcFile = CreateFile(Src, GENERIC_READ, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    	if (hSrcFile == INVALID_HANDLE_VALUE) {
    		std::cout << "CreateFile Failed" << std::endl;
    		return FALSE;
    	}
    
    	LARGE_INTEGER lpFileSize;
    	if (!GetFileSizeEx(hSrcFile, &lpFileSize)) {
    		std::cout << "GetFileSize Failed" << std::endl;
    		std::cout << GetLastError() << std::endl;
    		return FALSE;
    	}
    
    	CHAR* szBuffer = new CHAR[lpFileSize.LowPart + 1];
    	if (szBuffer == nullptr) {
    		std::cout << "申请内存失败!" << std::endl;
    		return FALSE;
    	}
    	memset(szBuffer, 0, lpFileSize.LowPart + 1);
    
    	DWORD lpNumberOfBytesRead;
    	BOOL bRet = ReadFile(hSrcFile, szBuffer, lpFileSize.LowPart, &lpNumberOfBytesRead, NULL);
    	if (!bRet) {
    		std::cout << "ReadFile Failed!" << std::endl;
    		return FALSE;
    	}
    
    	HANDLE hNewFile = CreateFile(New, GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    	if (hNewFile == INVALID_HANDLE_VALUE) {
    		std::cout << "CreateFile Failed!" << std::endl;
    		return FALSE;
    	}
    
    	DWORD lpNumberOfBytesWritten;
    	bRet = WriteFile(hNewFile, szBuffer, lpFileSize.LowPart, &lpNumberOfBytesWritten, NULL);
    	if (!bRet) {
    		std::cout << "WriteFile Failed!" << std::endl;
    		return FALSE;
    	}
    
    	DeleteFile(Src);
    
    	CloseHandle(hSrcFile);
    	CloseHandle(hNewFile);
    	delete(szBuffer);
    	return TRUE;
    }
    
  3. 自己实现一个删除非空目录的函数
    void ReadDirectory(LPCWSTR lpDirectory)
    {
    	WIN32_FIND_DATAW FindFileData;
    	HANDLE hFile = FindFirstFile((std::wstring(lpDirectory) + L"\\*").c_str(), &FindFileData);
    
    	if (hFile == INVALID_HANDLE_VALUE) {
    		std::wcout << "FindFirstFile Failed" << std::endl;
    		return;
    	}
    
    	do {
    		// 判断是否为目录:
    		if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
    			if (wcscmp(FindFileData.cFileName, L".") != 0 && wcscmp(FindFileData.cFileName, L"..") != 0) {
    				// 构建新的路径并递归调用
    				std::wstring newPath = std::wstring(lpDirectory) + L"\\" + FindFileData.cFileName;
    				ReadDirectory(newPath.c_str());
    
    				// 在递归之后删除目录
    				RemoveDirectory(newPath.c_str());
    			}
    		}
    		else {
    			// 构建文件的完整路径
    			std::wstring filePath = std::wstring(lpDirectory) + L"\\" + FindFileData.cFileName;
    
    			// 删除文件
    			if (DeleteFile(filePath.c_str())) {
    				std::wcout << "Deleted: " << filePath << std::endl;
    			}
    			else {
    				std::wcout << "Failed to delete: " << filePath << std::endl;
    			}
    		}
    	} while (FindNextFile(hFile, &FindFileData));
    	RemoveDirectory(lpDirectory);
    	FindClose(hFile);
    }
    
  4. 自己实现递归遍历文件的函数
    void ReadDirectory(LPCWSTR lpDirectory, int nCount = 0)
    {
    	WIN32_FIND_DATAW FindFileData;
    	HANDLE hFile = FindFirstFile((std::wstring(lpDirectory) + L"\\*").c_str(), &FindFileData);
    
    	if (hFile == INVALID_HANDLE_VALUE) {
    		std::wcout << "FindFirstFile Failed" << std::endl;
    		return;
    	}
    
    	do {
    		// 判断是否为目录:
    		if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
    			if (wcscmp(FindFileData.cFileName, L".") != 0 && wcscmp(FindFileData.cFileName, L"..") != 0) {
    				std::wcout << std::wstring(nCount, L' ') << "(Directory) ";
    				std::wcout << FindFileData.cFileName << ":";
    
    				// 处理时间:
    				SYSTEMTIME Systime;
    				FileTimeToSystemTime(&FindFileData.ftCreationTime, &Systime);
    				std::wcout << Systime.wYear << "-" << Systime.wMonth << "-" << Systime.wDay
    					<< "-" << Systime.wHour << "-" << Systime.wMinute << std::endl;
    
    				// 构建新的路径并递归调用
    				std::wstring newPath = std::wstring(lpDirectory) + L"\\" + FindFileData.cFileName;
    				ReadDirectory(newPath.c_str(), nCount + 1);
    			}
    		}
    		else {
    			std::wcout << std::wstring(nCount, L' ');
    			std::wcout << FindFileData.cFileName << ":";
    
    			// 处理时间:
    			SYSTEMTIME Systime;
    			FileTimeToSystemTime(&FindFileData.ftCreationTime, &Systime);
    			std::wcout << Systime.wYear << "-" << Systime.wMonth << "-" << Systime.wDay
    				<< "-" << Systime.wHour << "-" << Systime.wMinute << std::endl;
    		}
    	} while (FindNextFile(hFile, &FindFileData));
    
    	FindClose(hFile);
    }
    
  5. 遍历某一个文件夹的文件后,对其加密(异或)(虚拟机实验)
    // 加密文件夹.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    
    #include 
    #include 
    #include 
    
    BOOL EncipherFile(LPCWSTR lpDirectory);
    BOOL EncipherDocument(LPCWSTR lpDirectory);
    
    int main()
    {
    	if (EncipherFile(L"E:\\Test")) {
    		std::cout << L"加密完成" << std::endl;
    	}
    	else {
    		std::cout << L"加密失败" << std::endl;
    	}
    }
    
    BOOL EncipherFile(LPCWSTR lpDirectory)
    {
    	WIN32_FIND_DATAW FindFileData;
    	HANDLE hFile = FindFirstFile((std::wstring(lpDirectory) + L"\\*").c_str(), &FindFileData);
    
    	if (hFile == INVALID_HANDLE_VALUE) {
    		std::wcout << "FindFirstFile Failed" << std::endl;
    		return FALSE;
    	}
    
    	do {
    		// 判断是否为目录:
    		if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
    			if (wcscmp(FindFileData.cFileName, L".") != 0 && wcscmp(FindFileData.cFileName, L"..") != 0) {
    				// 构建新的路径并递归调用
    				std::wstring newPath = std::wstring(lpDirectory) + L"\\" + FindFileData.cFileName;
    				EncipherFile(newPath.c_str());
    			}
    		}
    		else {
    			// 构建文件的完整路径
    			std::wstring filePath = std::wstring(lpDirectory) + L"\\" + FindFileData.cFileName;
    
    			// 加密文件
    			if (EncipherDocument(filePath.c_str())) {
    				std::wcout << L"Successfull Encipher" << filePath << std::endl;
    			}
    			else {
    				std::wcout << "Failed to Encipher: " << filePath << std::endl;
    			}
    		}
    	} while (FindNextFile(hFile, &FindFileData));
    
    	FindClose(hFile);
    
    	return TRUE;
    }
    
    BOOL EncipherDocument(LPCWSTR lpDirectory)
    {
    	BOOL bRet;
    	HANDLE hFile = CreateFile(lpDirectory, GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    	if (hFile == INVALID_HANDLE_VALUE) {
    		return FALSE;
    	}
    
    	//获取文件大小
    	LARGE_INTEGER FileSize;
    	bRet = GetFileSizeEx(hFile, &FileSize);
    	if (!bRet) {
    		std::cout << "Faild to GetFileSize" << std::endl;
    		return FALSE;
    	}
    
    	CHAR* szBuffer = new CHAR[FileSize.LowPart + 1];
    	memset(szBuffer, 0, FileSize.LowPart + 1);
    
    	//读文件
    	DWORD lpNumberOfBytesRead;
    	bRet = ReadFile(hFile, szBuffer, FileSize.LowPart, &lpNumberOfBytesRead, NULL);
    	if (!bRet) {
    		std::cout << L"Failed to ReadFile" << std::endl;
    		return FALSE;
    	}
    
    	for (size_t i = 0; i < FileSize.LowPart; i++)
    	{
    		szBuffer[i] ^= 'a';
    	}
    
    	//移动文件指针
    	SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
    
    	//写入文件
    	DWORD lpNumberOfBytesWritten;
    	bRet = WriteFile(hFile, szBuffer, FileSize.LowPart, &lpNumberOfBytesWritten, NULL);
    	if (!bRet) {
    		std::cout << L"Failed to WriteFile!" << std::endl;
    		return FALSE;
    	}
    	std::cout << "Successful Enciph:" << lpDirectory << std::endl;
    
    	CloseHandle(hFile);
    	return 0;
    }
    
    
#include 
#include 

int main(){
  //ASCII UNICODE
  //相互转换:
  Windows API都有版本: A W EX
  ASCII UNICODE 拓展版本
  
  MessageBox()
  
  system("pause");
  return 0;
}

文件,内核对象

#include 
#include 

int main()
{
	//打开文件或I/O设备
	HANDLE hFile = CreateFile(L"E:\\Test A\\111.txt",   //文件名
		GENERIC_READ | GENERIC_WRITE,                   //打开方式
		NULL,                                           //共享模式,这里NULL是独占
		NULL,                                           //安全属性
		OPEN_ALWAYS,                                    //要对存在或不存在的文件或设备进行的操作
		FILE_ATTRIBUTE_NORMAL,                          //文件或设备属性
		NULL
	);

	//INVALID_HANDLE_VALUE宏是微软提出的专门用于判断句柄是否有效的宏
	if (hFile == INVALID_HANDLE_VALUE) {
		std::cout << "CreateFile Failed!" << std::endl;
	}

	//定义我们要写入文件的字符串
	CHAR* szBuffer[MAX_PATH] = { 0 };
	memcpy(szBuffer, "Hello Windows File!", sizeof("Hello Windows File!"));

	DWORD dwNumberOfBytesWritten = 0;
	BOOL bRet = WriteFile(
		hFile,                    //文件句柄
		szBuffer,                 //字符串地址
		sizeof("Hello Windows File!"),//写入文件大小
		&dwNumberOfBytesWritten,
		NULL
	);

	if (!bRet) {
		std::cout << "WriteFile Faild!" << std::endl;
	}

	CloseHandle(hFile);
	system("pause");
	return 0;
}

上述的是没有错误的操作流程

如果文件已经存在的话,就会出现错误

我们在开发过程中,如何定位错误?

监视->添加监视:err,hr

这样,如果出现错误,错误原因也就会显示了

或者,复制错误码,在工具:错误查找中,查找错误原因

或者:

std::cout<<GetLaseError()<<std::endl;
这样会直接打印出错误码
  • 读文件:

    #include 
    #include 
    
    int main()
    {
    	//打开文件或I/O设备
    	HANDLE hFile = CreateFile(L"E:\\Test A\\111.txt",   //文件名
    		GENERIC_READ | GENERIC_WRITE,                   //打开方式
    		NULL,                                           //共享模式,这里NULL是独占
    		NULL,                                           //安全属性
    		OPEN_ALWAYS,                                    //要对存在或不存在的文件或设备进行的操作
    		FILE_ATTRIBUTE_NORMAL,                          //文件或设备属性
    		NULL
    	);
    
    	//INVALID_HANDLE_VALUE宏是微软提出的专门用于判断句柄是否有效的宏
    	if (hFile == INVALID_HANDLE_VALUE) {
    		std::cout << "CreateFile Failed!" << std::endl;
    	}
    
    	//获取文件大小
    	LARGE_INTEGER lpFileSize;
    	/*
    	typedef union _LARGE_INTEGER {
    		struct {
    			DWORD LowPart;
    			LONG HighPart;
    		} DUMMYSTRUCTNAME;
    		struct {
    			DWORD LowPart;
    			LONG HighPart;
    		} u;
    		LONGLONG QuadPart;
    	} LARGE_INTEGER;
    	*/
    	if (!GetFileSizeEx(hFile, &lpFileSize
    		)) {
    		std::cout << "GetFileSize Failed!" << std::endl;
    		std::cout << "错误码:" << GetLastError() << std::endl;
    	}
    
    	//定义我们要读出文件的字符串
    	CHAR* szBuffer = new CHAR[lpFileSize.LowPart + 1];
    	memset(szBuffer, 0, lpFileSize.LowPart + 1);
    
    	DWORD lpNumberOfBytesRead;
    	BOOL bRet = ReadFile(hFile,
    		szBuffer,
    		lpFileSize.LowPart,
    		&lpNumberOfBytesRead,
    		NULL
    	);
    
    	if (bRet) {
    		std::cout << szBuffer << std::endl;
    	}
    	else {
    		std::cout << "ReadFile Faild!" << std::endl;
    	}
    
    	CloseHandle(hFile);
    	system("pause");
    	return 0;
    }
    
    
  • 移动文件:

    	//移动文件
    	if (MoveFile(L"E:\\Test A\\111.txt", L"E:\\Test B\\222.txt")) {
    		std::cout << "移动成功" << std::endl;
    	}
    	else {
    		std::cout << "移动失败!" << std::endl;
    	}
    
    	//删除文件
    	if (DeleteFile(L"E:\\Test B\\222.txt")) {
    		std::cout << "删除成功" << std::endl;
    	}
    	else {
    		std::cout << "删除失败!" << std::endl;
    	}
    
    	//拷贝文件
    	if (CopyFile(L"E:\\Test B\\222 - 副本.txt", L"E:\\Test A\\111.txt", TRUE)) {
    		std::cout << "移动成功" << std::endl;
    	}
    	else {
    		std::cout << "移动失败!" << std::endl;
    	}
    
    

目录

	//创建新目录:
	CreateDirectory(L"E:\\Test C", NULL);
	//删除目录(只能删除空目录):
	RemoveDirectory(L"E:\\Test C");

	//遍历文件目录:
	WIN32_FIND_DATAW FindFileData;
	HANDLE hFile = FindFirstFile(L"E:\\*", &FindFileData);

	if (hFile == INVALID_HANDLE_VALUE) {
		std::cout << "FindFirstFile Failed" << std::endl;
	}

	do {
		//判断是否为目录:
		if (FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) {
			std::cout << "(Directory)";
		}

		std::cout << FindFileData.cFileName << ":";
		
		//处理时间:
		SYSTEMTIME Systime;
		FileTimeToSystemTime(&FindFileData.ftCreationTime, &Systime);
		std::cout << Systime.wYear << "-" << Systime.wMonth << "-" << Systime.wDay << "-" << Systime.wHour << "-" << Systime.wMinute << std::endl;


	} while (FindNextFile(hFile, &FindFileData));

.:当前路径

…:上级路径

一般如果想要遍历C盘文件,需要手动提权,或者:

属性页-连接器-清单文件,UAC执行级别:设置高级

获取单个文件详细信息

#include 
#include 

int main(){
	//获取单个文件详细信息:
	HANDLE hFile = CreateFile(L"E:\\Test A\\111.txt", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPWN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	BY_HANDLE_FILE_INFORMATION bhFileInfo;
	GetFileInformationByHandle(hFile, &bhFileInfo);
  std::cout<<......<<std::endl;
  system("pause");
  return 0;
}

盘符

A-Z

Z之后,挂硬盘挂不上去

A,B盘是软盘

获取磁盘类型:

UINT uRet = GetDriveType("C:");

查询磁盘相关信息:

GetVolumeInformation()

获取磁盘大小:

GetDiskFreeSpace("D:\\",...)

硬盘(卷)GUIID:

char szvolume[MAX_PATH]={0};
HANDLE hVolume = FindFirstVolume(szVolume,MAX_PATH);
std::cout<<szVolume<<std::endl;
while(FindNextVolume(hVolume,szVolume,MAX_PATH)){
  std::cout<<szVolume<<std::endl;
}
FindVolumeClostd(hVolume);

作业

  1. 自己实现拷贝文件功能(CopyFile)
    BOOL MyCopyFile(LPCWSTR Src, LPCWSTR New,BOOL nFlag)
    {
    	HANDLE hSrcFile = NULL;
    	switch (nFlag) {
    	case FALSE: {
    		hSrcFile = CreateFile(Src, GENERIC_READ, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    		if (hSrcFile == INVALID_HANDLE_VALUE) {
    			std::cout << "CreateFile Failed" << std::endl;
    			return FALSE;
    		}
    	}
    	case TRUE: {
    		hSrcFile = CreateFile(Src, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    		if (hSrcFile == INVALID_HANDLE_VALUE) {
    			std::cout << "CreateFile Failed" << std::endl;
    			return FALSE;
    		}
    	}
    	}
    
    	LARGE_INTEGER lpFileSize;
    	if (!GetFileSizeEx(hSrcFile, &lpFileSize)) {
    		std::cout << "GetFileSize Failed" << std::endl;
    		std::cout << GetLastError() << std::endl;
    		return FALSE;
    	}
    
    	CHAR* szBuffer = new CHAR[lpFileSize.LowPart + 1];
    	if (szBuffer == nullptr) {
    		std::cout << "申请内存失败!" << std::endl;
    		return FALSE;
    	}
    	memset(szBuffer, 0, lpFileSize.LowPart + 1);
    
    	DWORD lpNumberOfBytesRead;
    	BOOL bRet = ReadFile(hSrcFile, szBuffer, lpFileSize.LowPart, &lpNumberOfBytesRead, NULL);
    	if (!bRet) {
    		std::cout << "ReadFile Failed!" << std::endl;
    		return FALSE;
    	}
    
    	HANDLE hNewFile = CreateFile(New, GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    	if (hNewFile == INVALID_HANDLE_VALUE) {
    		std::cout << "CreateFile Failed!" << std::endl;
    		return FALSE;
    	}
    
    	DWORD lpNumberOfBytesWritten;
    	bRet = WriteFile(hNewFile, szBuffer, lpFileSize.LowPart, &lpNumberOfBytesWritten, NULL);
    	if (!bRet) {
    		std::cout << "WriteFile Failed!" << std::endl;
    		return FALSE;
    	}
    
    	CloseHandle(hSrcFile);
    	CloseHandle(hNewFile);
    	delete(szBuffer);
    	return TRUE;
    }
    
  2. 自己实现移动文件(MoveFile)功能
    BOOL MyMoveFile(LPCWSTR Src, LPCWSTR New)
    {
    	HANDLE hSrcFile = CreateFile(Src, GENERIC_READ, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    	if (hSrcFile == INVALID_HANDLE_VALUE) {
    		std::cout << "CreateFile Failed" << std::endl;
    		return FALSE;
    	}
    
    	LARGE_INTEGER lpFileSize;
    	if (!GetFileSizeEx(hSrcFile, &lpFileSize)) {
    		std::cout << "GetFileSize Failed" << std::endl;
    		std::cout << GetLastError() << std::endl;
    		return FALSE;
    	}
    
    	CHAR* szBuffer = new CHAR[lpFileSize.LowPart + 1];
    	if (szBuffer == nullptr) {
    		std::cout << "申请内存失败!" << std::endl;
    		return FALSE;
    	}
    	memset(szBuffer, 0, lpFileSize.LowPart + 1);
    
    	DWORD lpNumberOfBytesRead;
    	BOOL bRet = ReadFile(hSrcFile, szBuffer, lpFileSize.LowPart, &lpNumberOfBytesRead, NULL);
    	if (!bRet) {
    		std::cout << "ReadFile Failed!" << std::endl;
    		return FALSE;
    	}
    
    	HANDLE hNewFile = CreateFile(New, GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    	if (hNewFile == INVALID_HANDLE_VALUE) {
    		std::cout << "CreateFile Failed!" << std::endl;
    		return FALSE;
    	}
    
    	DWORD lpNumberOfBytesWritten;
    	bRet = WriteFile(hNewFile, szBuffer, lpFileSize.LowPart, &lpNumberOfBytesWritten, NULL);
    	if (!bRet) {
    		std::cout << "WriteFile Failed!" << std::endl;
    		return FALSE;
    	}
    
    	DeleteFile(Src);
    
    	CloseHandle(hSrcFile);
    	CloseHandle(hNewFile);
    	delete(szBuffer);
    	return TRUE;
    }
    
  3. 自己实现一个删除非空目录的函数
    void ReadDirectory(LPCWSTR lpDirectory)
    {
    	WIN32_FIND_DATAW FindFileData;
    	HANDLE hFile = FindFirstFile((std::wstring(lpDirectory) + L"\\*").c_str(), &FindFileData);
    
    	if (hFile == INVALID_HANDLE_VALUE) {
    		std::wcout << "FindFirstFile Failed" << std::endl;
    		return;
    	}
    
    	do {
    		// 判断是否为目录:
    		if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
    			if (wcscmp(FindFileData.cFileName, L".") != 0 && wcscmp(FindFileData.cFileName, L"..") != 0) {
    				// 构建新的路径并递归调用
    				std::wstring newPath = std::wstring(lpDirectory) + L"\\" + FindFileData.cFileName;
    				ReadDirectory(newPath.c_str());
    
    				// 在递归之后删除目录
    				RemoveDirectory(newPath.c_str());
    			}
    		}
    		else {
    			// 构建文件的完整路径
    			std::wstring filePath = std::wstring(lpDirectory) + L"\\" + FindFileData.cFileName;
    
    			// 删除文件
    			if (DeleteFile(filePath.c_str())) {
    				std::wcout << "Deleted: " << filePath << std::endl;
    			}
    			else {
    				std::wcout << "Failed to delete: " << filePath << std::endl;
    			}
    		}
    	} while (FindNextFile(hFile, &FindFileData));
    	RemoveDirectory(lpDirectory);
    	FindClose(hFile);
    }
    
  4. 自己实现递归遍历文件的函数
    void ReadDirectory(LPCWSTR lpDirectory, int nCount = 0)
    {
    	WIN32_FIND_DATAW FindFileData;
    	HANDLE hFile = FindFirstFile((std::wstring(lpDirectory) + L"\\*").c_str(), &FindFileData);
    
    	if (hFile == INVALID_HANDLE_VALUE) {
    		std::wcout << "FindFirstFile Failed" << std::endl;
    		return;
    	}
    
    	do {
    		// 判断是否为目录:
    		if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
    			if (wcscmp(FindFileData.cFileName, L".") != 0 && wcscmp(FindFileData.cFileName, L"..") != 0) {
    				std::wcout << std::wstring(nCount, L' ') << "(Directory) ";
    				std::wcout << FindFileData.cFileName << ":";
    
    				// 处理时间:
    				SYSTEMTIME Systime;
    				FileTimeToSystemTime(&FindFileData.ftCreationTime, &Systime);
    				std::wcout << Systime.wYear << "-" << Systime.wMonth << "-" << Systime.wDay
    					<< "-" << Systime.wHour << "-" << Systime.wMinute << std::endl;
    
    				// 构建新的路径并递归调用
    				std::wstring newPath = std::wstring(lpDirectory) + L"\\" + FindFileData.cFileName;
    				ReadDirectory(newPath.c_str(), nCount + 1);
    			}
    		}
    		else {
    			std::wcout << std::wstring(nCount, L' ');
    			std::wcout << FindFileData.cFileName << ":";
    
    			// 处理时间:
    			SYSTEMTIME Systime;
    			FileTimeToSystemTime(&FindFileData.ftCreationTime, &Systime);
    			std::wcout << Systime.wYear << "-" << Systime.wMonth << "-" << Systime.wDay
    				<< "-" << Systime.wHour << "-" << Systime.wMinute << std::endl;
    		}
    	} while (FindNextFile(hFile, &FindFileData));
    
    	FindClose(hFile);
    }
    

你可能感兴趣的:(Windows系统编程,windows,笔记)