win32api之文件系统管理(七)
什么是文件系统
文件系统是一种用于管理计算机存储设备上文件和目录的机制。文件系统为文件和目录分配磁盘空间,管理文件和目录的存储和检索,以及提供对它们的访问和共享,以下是常见的两种文件系统:
NTFS | FAT32 | |
---|---|---|
磁盘分区容量 | 2T | 32G |
单个文件容量 | 4G以上 | 最大4G |
EFS加密 | 支持 | 不支持 |
磁盘配额 | 支持 | 不支持 |
什么是卷
卷是操作系统对磁盘分区的逻辑抽象,可以看作是磁盘分区的容器。在一个物理磁盘中可以分为多个卷,每个卷可以分配不同的文件系统,从而实现对数据的管理和存储
每个卷都有一个唯一的卷标识符,可以通过这个标识符来访问和管理它的数据
卷相关API
GetLogicalDrives
GetLogicalDrivers函数用于获取当前系统中存在卷的数量,其返回值为一个32位无符号整数,每个比特位表示一个卷的状态。若比特位为1,则代表对应的卷存在,其语法格式如下:
DWORD GetLogicalDrives(void);
以下是常见的返回值以及对应的含义:
- 返回值为0x01(二进制为0001):表示只有A盘存在
- 返回值为0x02(二进制为0010):表示只有B盘存在;
- 返回值为0x03(二进制为0011):表示A盘和B盘都存在;
- 返回值为0x04(二进制为0100):表示只有C盘存在;
- 返回值为0x0C(二进制为1100):表示只有C盘和D盘存在
- 返回值为0X0F(二进制为1111):表示ABCD盘都存在
GetLogicalDriveStrings
GetLogicalDriveStrings函数用于获取系统上所有逻辑驱动器的名称和根目录,换句话说就是获取卷的标识符,函数调用成功后,函数返回值为返回的字符数组中的字符数,若函数失败,则返回值为0
其语法格式如下:
DWORD GetLogicalDriveStrings(
DWORD nBufferLength, //存储驱动器名称的缓冲区的大小
LPTSTR lpBuffer //指向缓冲区的指针
);
GetDriveType
GetDriveType函数用于获取指定驱动器的类型
UINT GetDriveType(
LPCWSTR lpRootPathName //要获取其驱动器类型的根目录路径
);
其返回值是一个整数,代表驱动器的类型,取值如下:
-
DRIVE_UNKNOWN(0):未知类型的驱动器。
-
DRIVE_NO_ROOT_DIR(1):驱动器不存在或根路径无效。
-
DRIVE_REMOVABLE(2):可移动磁盘。
-
DRIVE_FIXED(3):固定磁盘。
-
DRIVE_REMOTE(4):网络驱动器。
-
DRIVE_CDROM(5):光盘驱动器。
-
DRIVE_RAMDISK(6):RAM磁盘。
GetVolumeInformation
GetVolumeInformation函数用于获取卷的相关信息(如卷名称、文件系统、卷序列号等)。如果函数执行成功,则返回值为TRUE;如果执行失败,则返回值为FALSE
其语法格式如下:
BOOL GetVolumeInformation(
LPCWSTR lpRootPathName, // IN 指定驱动器的根路径
LPWSTR lpVolumeNameBuffer, // OUT 接收卷名称的缓冲区
DWORD nVolumeNameSize, // IN 缓冲区大小(以字符数为单位)
LPDWORD lpVolumeSerialNumber, // OUT 接收卷序列号的指针
LPDWORD lpMaximumComponentLength, // OUT 接收最大文件名称长度的指针
LPDWORD lpFileSystemFlags, // OUT 接收文件系统标识的指针
LPWSTR lpFileSystemNameBuffer, // OUT 接收文件系统名称的缓冲区
DWORD nFileSystemNameSize // IN文件系统名称缓冲区大小
);
使用实例
include <windows.h>
include <bitset>
int main()
{
//获取卷的数量
DWORD dwLogicalDrivers = GetLogicalDrives();
//将十进制转换成二进制并输出
std::bitset<8> bits(dwLogicalDrivers);
std::cout <<"卷的状态是:"<< bits.to_string()<<std::endl;
// 遍历所有卷的标识符
TCHAR szBuffer[100];
GetLogicalDriveStrings(20, szBuffer);
std::cout << "卷的标识符有:";
for (TCHAR* drive = szBuffer; *drive != '\0'; drive += lstrlen(drive) + 1) {
std::cout << drive << ",";
}
std::cout<<std::endl;
//获取卷的类型
UINT DriveType = GetDriveType("D:\\");
printf("卷的类型是:%u\n", DriveType);
//获取卷的信息
TCHAR VolumeName[200] = { 0 };
DWORD VolumeSerial = 0;
DWORD MaxLength = 0;
DWORD FileSystemIDC = 0;
TCHAR FileSystemName[200] = { 0 };
GetVolumeInformation(
"E:\\",
VolumeName,
200,
&VolumeSerial,
&MaxLength,
&FileSystemIDC,
FileSystemName,
200
);
printf("卷名=%s\n序列号=%d\n文件系统标识=%d\n文件系统名称=%s", VolumeName, VolumeSerial,FileSystemIDC,FileSystemName);
}
执行结果如下:
目录相关API
CreateDirectory
CreateDirectory函数用于创建一个新目录,其语法格式如下:
BOOL CreateDirectory(
LPCTSTR lpPathName, //要创建的目录的名称和路径,可以是绝对路径或相对路径
LPSECURITY_ATTRIBUTES lpSecurityAttributes //指定了新目录的安全性和访问控制
);
RemoveDirectory
RemoveDirectory函数用于删除指定目录及其所有内容
BOOL RemoveDirectory(
LPCTSTR lpPathName //要删除的目录路径
);
MoveFile
MoveFile函数用于将一个文件或目录移动到新的位置,其语法格式如下:
BOOL MoveFile(
LPCWSTR lpExistingFileName, //要移动的文件或目录的名称
LPCWSTR lpNewFileName //移动后的新位置的路径和名称
);
GetCurrentDirectory
GetCurrentDirectory函数用于获取当前进程的工作目录。其函数原型为
DWORD GetCurrentDirectory(
DWORD nBufferLength, // 缓冲区大小,单位为字节
LPTSTR lpBuffer // 存储路径的缓冲区
);
SetCurrentDirectory
SetCurrentDirectory函数用于设置当前进程的工作目录,其语法格式如下:
BOOL SetCurrentDirectory(
LPCWSTR lpPathName //新的进程工作目录
);
文件相关API
CreateFile
CreateFile函数是一个用于创建或打开文件, 它可以用于创建、读取、写入、修改文件, 函数返回一个文件的句柄, 若执行失败则返回无效句柄值,其语法格式如下:
HANDLE CreateFile(
LPCTSTR lpFileName, //创建的文件名
DWORD dwDesiredAccess, //文件访问模式
DWORD dwShareMode, //共享模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes, //安全描述符
DWORD dwCreationDisposition, //文件的创建方式
DWORD dwFlagsAndAttributes, //文件的属性和标志
HANDLE hTemplateFile //指定要用作新文件的属性模板的句柄
);
dwDesiredAccess参数用于指定文件的访问方式, 如下是常见的dwDesiredAccess值:
GENERIC_READ
:读取文件GENERIC_WRITE
:写入文件GENERIC_EXECUTE
:执行文件GENERIC_ALL
:允许读、写和删除文件
若要指定多个访问方式,可使用OR连接起来,如GENERIC_READ | GENERIC_WRITE
dwShareMode参数指定了其他进程是否可以访问已经打开的文件或设备,如下是常见的值:
FILE_SHARE_READ
:允许其他进程读取文件或设备。FILE_SHARE_WRITE
:允许其他进程写入文件或设备。FILE_SHARE_DELETE
:允许其他进程删除文件或设备。
默认情况下,dwShareMode的值为0,即文件或设备不能被共享访问
dwCreationDisposition
参数用于指定创建或打开文件的方式,以下是可取的值:
CREATE_NEW
:如果文件不存在,则创建文件;否则,打开失败。CREATE_ALWAYS
:如果文件不存在,则创建文件。若文件存在,则覆盖该文件OPEN_EXISTING
:打开现有文件。如果文件不存在,则打开失败,并返回错误ERROR_FILE_NOT_FOUND
。OPEN_ALWAYS
:如果文件存在,则打开文件;否则,创建文件。TRUNCATE_EXISTING
:打开现有文件,并将其长度截断为零。如果文件不存在,则打开失败,并返回错误ERROR_FILE_NOT_FOUND
。
dwFlagsAndAttributes
参数是一个标志位,它用于指定创建或打开文件时的一些特殊选项,以下是常见的值
FILE_ATTRIBUTE_ARCHIVE
:文件存档属性。如果应用程序修改了存档文件,则操作系统会自动清除此属性。FILE_ATTRIBUTE_HIDDEN
:隐藏文件或目录。FILE_ATTRIBUTE_NORMAL
:标准文件属性。此属性没有任何其他属性设置。FILE_ATTRIBUTE_READONLY
:只读文件或目录。如果应用程序尝试修改只读文件,则会导致失败。FILE_ATTRIBUTE_DIRECTORY
:指示文件是目录。
GetFileSize
GetFileSize函数用于获取文件的大小,其语法格式如下:
DWORD WINAPI GetFileSize(
HANDLE hFile, //文件句柄
LPDWORD lpFileSizeHigh //接收文件大小的指针变量
);
GetFileAttributeEx
GetFileAttributeEx函数用于获取指定文件或目录的属性信息,其语法格式如下:
BOOL GetFileAttributesEx(
LPCWSTR lpFileName, //要获取属性的文件或目录名
GET_FILEEX_INFO_LEVELS fInfoLevelId, //指定文件信息的级别,一般设为GetFileExInfoStandard
LPVOID lpFileInformation //接收文件属性信息的缓冲区指针
);
以下是此函数的使用实例:
include <windows.h>
include <iostream>
int main() {
WIN32_FILE_ATTRIBUTE_DATA fileData; // 创建WIN32_FILE_ATTRIBUTE_DATA结构体变量fileData
if (GetFileAttributesEx(L"C:\\Windows", GetFileExInfoStandard, &fileData)) { // 获取"C:\\Windows"目录的文件属性,并将属性信息保存在fileData中
std::cout << "SizeHigh: " << fileData.nFileSizeHigh << std::endl; // 输出文件大小的高32位
std::cout << "SizeLow: " << fileData.nFileSizeLow << std::endl; // 输出文件大小的低32位
std::cout << "FileAttributes: " << fileData.dwFileAttributes << std::endl; // 输出文件属性
std::cout << "CreationTime: " << fileData.ftCreationTime.dwLowDateTime << std::endl; // 输出创建时间的低32位
std::cout << "LastAccessTime: " << fileData.ftLastAccessTime.dwLowDateTime << std::endl; // 输出最后访问时间的低32位
std::cout << "LastWriteTime: " << fileData.ftLastWriteTime.dwLowDateTime << std::endl; // 输出最后修改时间的低32位
}
return 0;
}
SetFilePointer
SetFilePointer函数用于设置文件指针的位置, 如果函数执行成功,则返回文件指针的新位置, 它的语法如下:
DWORD SetFilePointer(
HANDLE hFile, // 文件句柄
LONG lDistanceToMove, // 文件指针移动的距离,可以为正或负,负数表示向前移动,正数表示向后移动
PLONG lpDistanceToMoveHigh, // 文件指针移动的高位,常置为NULL
DWORD dwMoveMethod // 文件指针的起始位置
);
dwMoveMethod参数表示文件指针的起始位置, 以下是常见值:
FILE_BEGIN
:文件开头。FILE_CURRENT
:文件指针当前位置。FILE_END
:文件结尾。
ReadFile
ReadFile函数用于从文件中读取数据, 果读取成功,则函数返回TRUE,否则返回FALSE
它的语法格式如下:
BOOL ReadFile(
HANDLE hFile, //要读取的文件的句柄
LPVOID lpBuffer, //指向缓冲区的指针,用于存储从文件中读取的数据
DWORD nNumberOfBytesToRead, //要读取的字节数
LPDWORD lpNumberOfBytesRead, //指向一个变量的指针,用于接收实际读取的字节数数
LPOVERLAPPED lpOverlapped //指向OVERLAPPED结构体的指针,用于支持异步I/O操作,可以传递NULL以进行同步操作
);
WriteFile
WriteFile函数用于将数据写入到文件,其语法格式如下:
BOOL WriteFile(
HANDLE hFile, //文件句柄
LPCVOID lpBuffer, //指向待写入数据的缓冲区指针
DWORD nNumberOfBytesToWrite, //待写入数据的字节数
LPDWORD lpNumberOfBytesWritten, //用于接收实际写入的字节数的指针
LPOVERLAPPED lpOverlapped
);
CopyFile
CopyFile函数用于将一个文件复制到另一个位置,其语法格式如下:
BOOL CopyFile(
LPCWSTR lpExistingFileName, // 源文件名
LPCWSTR lpNewFileName, // 目标文件名
BOOL bFailIfExists // 目标文件存在时是否覆盖
);
DeleteFile
Delete函数用于删除指定路径下的文件,其语法格式如下:
BOOL DeleteFile(
LPCWSTR lpFileName //要删除的文件的路径
);
FindFirstFile
FindFirstFile
函数用于查找指定目录中的第一个文件或子目录,并返回句柄以供以后的查找使用,通过该句柄可以遍历该目录下的所有符合条件的文件或目录,其语法格式如下所示:
HANDLE FindFirstFile(
LPCTSTR lpFileName, // 文件名或路径模板
LPWIN32_FIND_DATA lpFindFileData // 指向 WIN32_FIND_DATA结构的指针
);
FindNextFile
FindNextFile
函数是在使用 FindFirstFile
函数后,用于在指定的目录中继续查找符合条件的文件或目录的函数,其语法格式如下:
BOOL FindNextFile(
HANDLE hFindFile, // FindFirstFile函数返回的句柄
LPWIN32_FIND_DATA lpFindFileData // WIN32_FIND_DATA 结构体指针,保存查找到的文件信息
);
以下代码用于遍历E盘目录下的所有txt文件
include <Windows.h>
include <iostream>
include <string>
int main()
{
std::string path = "E:\\*.txt";
WIN32_FIND_DATAA FindFileData;
HANDLE hFind = FindFirstFileA(path.c_str(), &FindFileData);
if (hFind == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to find file." << std::endl;
return 1;
}
do {
std::cout << FindFileData.cFileName << std::endl;
} while (FindNextFileA(hFind, &FindFileData));
FindClose(hFind); //释放文件句柄
return 0;
}