Windows系统编程(一)文件与目录操作

本节讲述有关文件的各种操作

书写文件

文件:比如我们电脑磁盘中储存的文件,在Windows操作系统中文件就是PE文件

CreateFile():该API用于创建或打开文件或IO设备。

#include<iostream>
#include<Windows.h>
int main()
{
    HANDLE hFile = CreateFile("D:\\rkvir.ini", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);//创建一个文件 
    if (INVALID_HANDLE_VALUE == hFile) //如果文件创建失败INVALID_HANDLE_VALUE是一个宏,用于比对句柄是否有效
    {
	    std::cout << "CreateFile Failed!" << std::endl;//文字提示文件创建失败。监视下输入err,hr可查看每一步的正确或失败
	    std::cout << GetLastErroe() << std::endl; //打印错误码,通过工具->错误查找,输入错误码便可查询错误原因
    }
    CHAR * szBuffer[MAX_PATH] = { 0 }; //申请一个缓存空间用于我们书写文件内容
    memcpy(szBuffer, "Hello File", strlen("Hello File")); //设置文件书写内容
    DWORD dwNumberOfBytesWritten = 0; // 用于接收文件写入的字节数
    BOOL bRet = WriteFile(hFile, szBuffer, strlen("Hello File"), &dwNumberOfBytesWritten, NULL); //文件写入
    if (!bRet) //如果文件写入失败
    {
        std::cout << "WriteFile Failed!" << std::endl; //文字提示文件书写失败
        std::cout << GetLastError() << std::endl; //打印错误码
    }
    CloseHandle(hFile); //关闭文件
    return 0;
}

读取文件

#include<iostream>
#include<Windows.h>
int main()
{
    HANDLE hFile = CreateFile("D:\\rkvir.ini", GENERIC_READ |     GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
    if (INVALID_HANDLE_VALUE == hFile) 
    {
        std::cout << "CreateFile Failed!" << std::endl; 
       	std::cout << GetLastError() << std::endl;
    }
    LARGE_INTEGER liFileSize; //由两个32位大小组成的64位结构体,用于存储大数
    if (!GetFileSizeEx(hFile, &liFileSize)) // GetFileSizeEx()获取文件大小,此处为获取失败时
    {
        std::cout << "GetFileSizeEx Failed!" << std::endl; 
        std::cout << GetLastError() << std::endl;
    }
     //SetFilePointer(hFile, 2, NULL, FILE_BEGIN); //用于偏移文件指定位置
     CHAR * szBuffer = new CHAR[liFileSize.LowPart + 1]; //创建一个读取文件信息的缓冲区。由于我们读写的文件数据比较小,因此用低32位即可。此处多申请一位大小用于00结尾防止内存越界
     memset(szBuffer, 0, liFileSize.LowPart + 1); //初始化缓冲区
     DWORD lpNumberOfBytesRead; 
     BOOL bRet = ReadFile(hFile, szBuffer, liFileSize.LowPart, &lpNumberOfBytesRead, NULL);//读取文件
    if (!bRet) 
    {
        std::cout << "ReadFile Failed!" << std::endl;
        std::cout << GetLastError() << std::endl;
    }
    std::cout << szBuffer << std::endl; 打印读取的内容,直到00结尾
    CloseHandle(hFile); //关闭文件
    return 0;
}

移动文件

#include<iostream>
#include<Windows.h>
int main()
{
	//方式一:直接移动文件
    MoveFile("D:\\Atest1\\rkvir.ini", "D:\\Atest2\\rkvir.ini");//移动文件至指定目录
    //方式二:复制删除实现移动文件 
    CopyFile("D:\\Atest1\\rkvir.ini", "D:\\Atest2\\rkvir.ini",TRUE);//复制一份文件至指定目录下
    DeleteFile("D:\\Atest2\\rkvir.ini"); //删除原文件,此时相当于移动了文件
    return 0;
}

目录操作

#include<iostream>
#include<Windows.h>
int main()
{
    CreateDirectory("D:\\Atest3", NULL); //创建一个目录
    RemoveDirectory("D:\\Atest3"); //只能删除空目录
    //遍历仅有文件的目录:
    WIN32_FIND_DATA FindFileData; //设置一个用于装载文件有关信息的结构体
    HANDLE hFile = FindFirstFile("D:\\Atest1\\*", &FindFileData); //指定目录下查找第一个文件
    if (INVALID_HANDLE_VALUE == hFile) //如果没有找到文件
    {
       	std::cout << "FindFirstFile Failed!" << std::endl;
        std::cout << GetLastError() << std::endl;
    }
    do
    {
        std::cout << FindFileData.cFileName << std::endl; //打印查找到的文件名字。注意打印的.指上级目录
       	SYSTEMTIME lpSystemTime; //设置一个用于设置系统时间和日期的结构
        FileTimeToSystemTime(&FindFileData.ftCreationTime, &lpSystemTime); //将文件时间转化成系统时间,否则打印的时间看不懂
       	std::cout << lpSystemTime.wYear << " " << lpSystemTime.wMonth << std::endl; //打印文件的时间年月
        if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)//当目标文件是一个目录时 
       	{
            std::cout << "DIRECTORY!" << std::endl;
       	}
} while (FindNextFile(hFile, &FindFileData)); 
    return 0;
}

获取指定文件属性

#include<iostream>
#include<Windows.h>
int main()
{
    HANDLE hFile = CreateFile("D:\\Atest1\\rkvir.ini", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATT RIBUTE_NORMAL, NULL); 
BY_HANDLE_FILE_INFORMATION bhFileInfo; //创建一个结构用于存储文件相关属性
    GetFileInformationByHandle(hFile, &bhFileInfo); //获取文件属性
    return 0;
}

磁盘

在Windows操作系统中,磁盘分为软盘和硬盘。其中A盘和B盘是软盘,C-Z是硬盘,超过Z以后,硬盘会不显示。

获取磁盘相关信息

#include<iostream>
#include<Windows.h>
int main()
{
	CHAR szVolumeNameBuffer[MAX_PATH] = { 0 };
    DWORD dwVolumeSerialNum;
    DWORD dwMaxCompoentLength;
    DWORD dwSysFlags;
    CHAR szFileSystemBuffer[MAX_PATH] = { 0 };
    UINT uRet = GetDriveType("C:");//获取目标磁盘类型
    GetVolumeInformation(“D:\\”, szVolumeNameBuffer, MAX_PATH, &dwVolumeSerialNum, & dwMaxCompoentLength, & dwSysFlags, szFileSystemBuffer, MAX_PATH);//获取磁盘相关信息
    DWORD lpSectorsPerCluster;
    DWORD lpBytesPerSector;
    DWORD lpNumberOfFreeClusters;
    DWORD lpTotalNumberOfClusters;
    GetDiskFreeSpace("D:\\", &lpSectorsPerCluster, &lpBytesPerSector, &lpNumberOfFreeClusters, &lpTotalNumberOfClusters); // 获取磁盘空闲大小
    return 0;
}

GUID

GUID是一种用于在计算机系统中唯一标识实体的标识符,每一个磁盘都有属于自己的GUID,相当于自己的身份证。当我们把我们使用的常见的加密播放器去更换硬盘存储地址的时候,播放器会对此检测出来。此时播放器会根据其所在磁盘的GUID来计算出特定的激活码,因此我们常常会因为播放器更换存储地址而需要重新获取激活码

遍历GUID

#include<iostream>
#include<Windows.h>
int main()
{
    char szvolume[MAX_PATH]={0};
HANDLE hVolume = FindFirstVolume(szVolume,MAX_PATH);//打开查找句柄并获取第一个磁盘的GUID 
    std::cout<<szVolume<<std::endl;
    while(FindNextVolume(hVolume,szVolume,MAX_PATH))
    {
      	std::cout<<szVolume<<std::endl;
    }
    FindVolumeClostd(hVolume);//关闭查找句柄
    return 0;
}

作业

 1.自己实现拷贝文件(CopyFile)功能

#include<iostream>
#include<windows.h>
BOOL FileSuc(HANDLE hFile)
{
	if (hFile == INVALID_HANDLE_VALUE)
	{
		std::cout << "CreateFile  Failed" << std::endl;
		return FALSE;
	}
	std::cout << "CreateFile Success" << std::endl;
	return TRUE;
}
BOOL MyCopyFile(CHAR* szBuffer, LARGE_INTEGER liFileSize, LPCWSTR NewFileName)
{
	HANDLE NewFile = CreateFile(NewFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	DWORD NumberOfBytesWritten;
	BOOL nRes = WriteFile(NewFile, szBuffer, liFileSize.LowPart, &NumberOfBytesWritten, NULL);
	if (nRes == FALSE)
	{
		std::cout << "WriteFile Failed" << std::endl;
		return FALSE;
	}
	std::cout << "WriteFile Success" << std::endl;
	CloseHandle(NewFile);
	return TRUE;
}
int main(int argc, char* argv[])
{
	LPCWSTR FileName = L"C:\\Users\\扶摇\\Desktop\\File.txt";
	HANDLE hFile = CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	LARGE_INTEGER FileSize;
	if (FileSuc(hFile) == FALSE)
	{
		return FALSE;
	}
	GetFileSizeEx(hFile, &FileSize);
	CHAR* szBuffer = new CHAR[FileSize.LowPart + 1];
	memset(szBuffer, 0, FileSize.LowPart + 1);
	DWORD NumberOfBytesRead;
	ReadFile(hFile, szBuffer, FileSize.LowPart, &NumberOfBytesRead, NULL);
	LPCWSTR NewFileName = L"C:\\Users\\扶摇\\Desktop\\NewFile.txt";
	MyCopyFile(szBuffer, FileSize, NewFileName);
	CloseHandle(hFile);
	delete[] szBuffer;
	return 0;
}

2.自己实现移动文件(MoveFile)功能

#include<iostream>
#include<windows.h>
BOOL FileSuc(HANDLE hFile)
{
	if (hFile == INVALID_HANDLE_VALUE)
	{
		std::cout << "CreateFile  Failed" << std::endl;
		return FALSE;
	}
	std::cout << "CreateFile Success" << std::endl;
	return TRUE;
}
BOOL MyCopyFile(CHAR* szBuffer, LARGE_INTEGER liFileSize, LPCWSTR NewFileName)
{
	HANDLE NewFile = CreateFile(NewFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	DWORD NumberOfBytesWritten;
	BOOL nRes = WriteFile(NewFile, szBuffer, liFileSize.LowPart, &NumberOfBytesWritten, NULL);
	if (nRes == FALSE)
	{
		std::cout << "WriteFile Failed" << std::endl;
		return FALSE;
	}
	std::cout << "WriteFile Success" << std::endl;
	CloseHandle(NewFile);
	return TRUE;
}
int main(int argc, char* argv[])
{
	LPCWSTR FileName = L"C:\\Users\\扶摇\\Desktop\\File.txt";
	HANDLE hFile = CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	LARGE_INTEGER FileSize;
	if (FileSuc(hFile) == FALSE)
	{
		return FALSE;
	}
	GetFileSizeEx(hFile, &FileSize);
	CHAR* szBuffer = new CHAR[FileSize.LowPart + 1];
	memset(szBuffer, 0, FileSize.LowPart + 1);
	DWORD NumberOfBytesRead;
	ReadFile(hFile, szBuffer, FileSize.LowPart, &NumberOfBytesRead, NULL);
	LPCWSTR NewFileName = L"C:\\Users\\扶摇\\Desktop\\NewFile.txt";
	MyCopyFile(szBuffer, FileSize, NewFileName);
	CloseHandle(hFile);
	DeleteFile(FileName);
	delete[] szBuffer;
	return 0;
}

3.自己实现一个删除非空目录的函数

#include<iostream>
#include<windows.h>
int main(int argc, char* argv[])
{
	LPCWSTR DirPath = L"C:\\text";
	LPCWSTR PathName = L"C:\\text\\*";
	WIN32_FIND_DATA FirstFile;
	HANDLE hFile = FindFirstFile(PathName, &FirstFile);
	BOOL hNextFile;
	LPCWSTR FileName = FirstFile.cFileName;
	if (hFile == INVALID_HANDLE_VALUE)
	{
		std::cout << "FindFile Failed,该目录为空" << std::endl;
		RemoveDirectory(PathName);
		std::wcout << DirPath << "目录已删除" << std::endl;
		return TRUE;
	}
	std::cout << "该目录存在文件" << std::endl;
	int FileNumber = 0;
	do
	{
		WIN32_FIND_DATA NextFile;
		std::wstring FinalFilePath = std::wstring(L"C:\\text\\") + std::wstring(FileName);
		if (FinalFilePath == std::wstring(DirPath) + L"\\.")
		{
			FindNextFile(hFile, &NextFile);
			FindNextFile(hFile, &NextFile);//跳过.和..目录
		}
		FileName = NextFile.cFileName;
		FinalFilePath = std::wstring(DirPath) + L"\\" + std::wstring(FileName);
		DeleteFile(FinalFilePath.c_str());
		std::wcout << "第" << FileNumber << "个文件" << FileName << "已删除" << std::endl;
		hNextFile = FindNextFile(hFile, &NextFile);
		FileName = NextFile.cFileName;
		FileNumber++;
	} while (hNextFile);
	RemoveDirectory(DirPath);
	std::cout << "该目录已删除" << std::endl;
	FindClose(hFile);
	return 0;
}

4.自己实现递归遍历文件的函数

#include<iostream>
#include<windows.h>
int FileNumber = 0;
int DirNumber = 0;
BOOL ErgodicDir(LPCWSTR DirPath)
{
	WIN32_FIND_DATA FirstFile;
	std::wstring PathName = std::wstring(DirPath) + L"\\*";
	HANDLE hFile = FindFirstFile(PathName.c_str(), &FirstFile);
	BOOL hNextFile;
	if (hFile == INVALID_HANDLE_VALUE)
	{
		std::cout << "FindFile Failed,该目录为空" << std::endl;
		return FALSE;
	}
	std::cout << "该目录存在文件" << std::endl;
	LPCWSTR FileName = FirstFile.cFileName;
	WIN32_FIND_DATA NextFile;
	do
	{
		std::wstring FinalFilePath = std::wstring(DirPath) + L"\\" + std::wstring(FileName);
		if (FinalFilePath == std::wstring(DirPath) + L"\\.")
		{
			FindNextFile(hFile, &NextFile);
			FindNextFile(hFile, &NextFile);//跳过.和..目录
		}
		FileName = NextFile.cFileName;
		FinalFilePath = std::wstring(DirPath) + L"\\" + std::wstring(FileName);
		if (NextFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			std::wcout << "遍历到第" << DirNumber << "个目录," << "现进入目录" << FinalFilePath  << std::endl;
			ErgodicDir(FinalFilePath.c_str());
			DirNumber++;
			hNextFile = FindNextFile(hFile, &NextFile);
		}
		else
		{
			std::wcout << "第" << FileNumber << "个文件" << FileName << std::endl;
			hNextFile = FindNextFile(hFile, &NextFile);
			FileName = NextFile.cFileName;
			FileNumber++;
		}
	} while (hNextFile);
	std::wcout << "该目标目录" << DirPath << "已遍历完毕" << std::endl;
}
int main(int argc, char* argv[])
{
	LPCWSTR DirPath = L"C:\\text";
	ErgodicDir(DirPath);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值