c,#includeint main() {, UINT drive = 0; // 0 for A:, 1 for B:, 2 for C:, etc., char rootPathName[4] = "C:\";, DWORD sectorsPerCluster, bytesPerSector, numberOfFreeClusters, totalNumberOfClusters; if (GetDiskFreeSpaceA(rootPathName, §orsPerCluster, &bytesPerSector, &numberOfFreeClusters, &totalNumberOfClusters)) {, printf("Drive %c:,", 'A' + drive);, printf("Sectors per cluster: %lu,", sectorsPerCluster);, printf("Bytes per sector: %lu,", bytesPerSector);, printf("Number of free clusters: %lu,", numberOfFreeClusters);, printf("Total number of clusters: %lu,", totalNumberOfClusters);, } else {, printf("Error retrieving disk information.,");, } return 0;,},
“
在C/C++中,读取磁盘信息是一个常见且重要的任务,尤其在系统管理、数据恢复和文件系统工具开发等领域,操作系统提供了丰富的API和库函数,使得开发者能够方便地获取磁盘的各种信息,如名称、容量、分区等,下面将详细介绍如何使用C API读取磁盘信息。
1. 使用CreateFile和ReadFile函数
在Windows平台上,可以使用CreateFile函数打开磁盘设备或分区,然后使用ReadFile函数按扇区读取磁盘数据,以下是一个简单的示例代码:
#include <windows.h> #include <stdio.h> int main() { HANDLE hDevice = CreateFile( "\\.\PhysicalDrive0", // 磁盘设备名称,\.PhysicalDrive0 表示第一个物理磁盘 GENERIC_READ, // 访问模式 FILE_SHARE_READ, // 共享模式 NULL, // 安全属性 OPEN_EXISTING, // 创建方式 FILE_ATTRIBUTE_NORMAL, // 文件属性 NULL); // 模板文件句柄 if (hDevice == INVALID_HANDLE_VALUE) { printf("Error opening device: %lu ", GetLastError()); return 1; } DWORD bytesRead; char buffer[512]; // 假设以扇区大小为单位进行读取,通常为512字节 if (!ReadFile(hDevice, buffer, sizeof(buffer), &bytesRead, NULL)) { printf("Error reading from device: %lu ", GetLastError()); CloseHandle(hDevice); return 1; } printf("Read %lu bytes from disk. ", bytesRead); // 处理读取到的数据... CloseHandle(hDevice); return 0; }
在这个示例中,首先使用CreateFile函数以只读模式打开第一个物理磁盘(\.PhysicalDrive0),如果成功,则使用ReadFile函数从磁盘中读取一个扇区的数据到缓冲区中,并输出读取的字节数,关闭设备句柄。
除了直接读取磁盘数据外,还可以使用Windows API获取磁盘的名称、卷标等信息,使用GetLogicalDriveStrings函数可以获取系统上所有逻辑驱动器的名称,而GetVolumeInformation函数可以获取指定磁盘的卷标信息。
#include <windows.h> #include <stdio.h> int main() { char driveStrings[1024]; DWORD driveStringsSize = sizeof(driveStrings); if (!GetLogicalDriveStrings(driveStringsSize, driveStrings)) { printf("Error getting logical drive strings: %lu ", GetLastError()); return 1; } char rootPathName[4] = "C:\"; // 根路径名,用于GetVolumeInformation函数 char volumeName[1024]; DWORD volumeNameSize = sizeof(volumeName); char fileSystemName[1024]; DWORD fileSystemNameSize = sizeof(fileSystemName); DWORD maxComponentLength; DWORD serialNumber; DWORD flags; if (!GetVolumeInformation(rootPathName, volumeName, volumeNameSize, &maxComponentLength, &serialNumber, &flags, fileSystemName, fileSystemNameSize)) { printf("Error getting volume information: %lu ", GetLastError()); return 1; } printf("Volume Name: %s ", volumeName); printf("File System Name: %s ", fileSystemName); // 其他信息... return 0; }
这个示例首先调用GetLogicalDriveStrings函数获取所有逻辑驱动器的名称,并存储在driveStrings数组中,使用GetVolumeInformation函数获取指定磁盘(这里以C盘为例)的卷标信息,包括卷标名称、文件系统名称等,并输出这些信息。
在Linux平台上,可以使用ioctl系统调用来获取磁盘设备的详细信息,包括设备名称、设备类型等,以下是一个使用ioctl系统调用获取磁盘名称的示例代码:
#include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include <fcntl.h> #include <linux/fs.h> #include <unistd.h> void get_disk_name(const char *device) { int fd = open(device, O_RDONLY); if (fd == -1) { perror("open"); return; } char disk_name[128]; if (ioctl(fd, BLKGETNAME, disk_name) == -1) { perror("ioctl"); } else { printf("Disk name: %s ", disk_name); } close(fd); } int main() { get_disk_name("/dev/sda"); // 替换为实际的磁盘设备文件路径 return 0; }
在这个示例中,首先使用open函数打开指定的磁盘设备文件(dev/sda),然后使用ioctl系统调用获取磁盘名称,并打印出来,关闭文件描述符。
2. 使用statvfs和getmntent函数
另一种在Linux平台上获取磁盘信息的方法是通过解析文件系统信息来实现,使用statvfs函数可以获取文件系统的统计信息,而getmntent函数可以获取挂载点的信息,以下是一个结合这两个函数来列出系统中所有挂载点的示例代码:
#include <stdio.h> #include <stdlib.h> #include <sys/statvfs.h> #include <mntent.h> void list_mount_points() { FILE *mnt_file = setmntent("/etc/mtab", "r"); if (mnt_file == NULL) { perror("setmntent"); return; } struct mntent *mnt; while ((mnt = getmntent(mnt_file)) != NULL) { struct statvfs vfs; if (statvfs(mnt->mnt_dir, &vfs) == 0) { printf("Mount point: %s, Device: %s ", mnt->mnt_dir, mnt->mnt_fsname); } else { perror("statvfs"); } } endmntent(mnt_file); } int main() { list_mount_points(); return 0; }
这个示例首先使用setmntent函数打开/etc/mtab文件(包含当前系统的所有挂载点信息),然后逐行读取文件中的挂载点信息,对于每个挂载点,使用statvfs函数获取文件系统的统计信息,并打印出挂载点和设备名称,调用endmntent函数关闭/etc/mtab文件。
Q1:如何判断一个磁盘是否存在于系统中?
A1:在Windows平台上,可以使用GetLogicalDrives函数来获取系统上所有逻辑磁盘的位图,然后通过检查位图中的每个位来确定某个磁盘是否存在,在Linux平台上,可以尝试打开指定的磁盘设备文件(如/dev/sda),如果open函数返回的文件描述符有效,则说明该磁盘存在,也可以使用ioctl系统调用来进一步验证磁盘的存在性。
Q2:如何获取磁盘的总容量和可用容量?
A2:在Windows平台上,可以使用GetDiskFreeSpaceEx函数来获取磁盘的总容量和可用容量,该函数会返回一个结构体,其中包含磁盘的总字节数、可用字节数等信息,在Linux平台上,可以使用statvfs函数来获取文件系统的统计信息,其中包括磁盘的总块数、空闲块数等,从而计算出磁盘的总容量和可用容量,具体计算方法可以根据文件系统的类型和块大小来确定。