C/C++實現(xiàn)磁盤相關(guān)操作的示例代碼
遍歷磁盤容量
如下代碼實現(xiàn)了在Windows系統(tǒng)中獲取所有磁盤驅(qū)動器的信息。具體包括兩個函數(shù),一個用于獲取驅(qū)動器類型,另一個用于獲取驅(qū)動器空間信息。主函數(shù)則調(diào)用這兩個函數(shù)來遍歷所有邏輯驅(qū)動器并輸出相應的信息。在輸出驅(qū)動器空間信息時,會輸出該驅(qū)動器的總大小、已用空間以及可用空間。
#include <stdio.h> #include <Windows.h> void GetDrivesType(const char* lpRootPathName) { UINT uDriverType = GetDriveType(lpRootPathName); switch (uDriverType) { case DRIVE_UNKNOWN:puts("未知磁盤"); break; case DRIVE_NO_ROOT_DIR: puts("路徑無效"); break; case DRIVE_REMOVABLE: puts("可移動磁盤"); break; case DRIVE_FIXED: puts("固定磁盤"); break; case DRIVE_REMOTE: puts("網(wǎng)絡磁盤"); break; case DRIVE_CDROM: puts("光驅(qū)"); break; case DRIVE_RAMDISK: puts("內(nèi)存映射盤"); break; default: break; } } void GetDrivesFreeSpace(const char* lpRootPathName) { unsigned long long available, total, free; if (GetDiskFreeSpaceEx(lpRootPathName, (ULARGE_INTEGER*)&available, (ULARGE_INTEGER*)&total, (ULARGE_INTEGER*)&free)) { printf("磁盤: %s | 總計: %lld MB 已用: %lld MB 剩余: %lld MB \n", lpRootPathName, total >> 20, available >> 20, free >> 20); } } int main(int argc,char *argv[]) { DWORD dwSize = MAX_PATH; char szLogicalDrives[MAX_PATH] = {0}; // 獲取邏輯驅(qū)動器號字符串 DWORD dwResult = GetLogicalDriveStringsA(dwSize, szLogicalDrives); if (dwResult > 0 && dwResult <= MAX_PATH) { // 從緩沖區(qū)起始地址開始 char* szSingleDrive = szLogicalDrives; while (*szSingleDrive) { //printf("Drive: %s\n", szSingleDrive); // 輸出單個驅(qū)動器的驅(qū)動器號 // GetDrivesType(szSingleDrive); GetDrivesFreeSpace(szSingleDrive); // 獲取下一個驅(qū)動器地址 szSingleDrive += strlen(szSingleDrive) + 1; } } system("pause"); return 0; }
遍歷盤符并存儲
循環(huán)遍歷盤符分區(qū),并將所有盤符結(jié)構(gòu)存儲到std::vector<MyDriver>
定義的容器中.
#include <windows.h> #include <iostream> #include <vector> #include <string> // 將字節(jié)轉(zhuǎn)換為GB單位顯示的宏定義 #define ToGB(x) (x.HighPart << 2) + (x.LowPart >> 20) / 1024.0 // 定義基礎結(jié)構(gòu) typedef struct { double available_space; double free_space; double total_space; }DriverInfo; // 定義完整結(jié)構(gòu) typedef struct { char driver_name[128]; char driver_type[128]; double available_space; double free_space; double total_space; }MyDriver; using namespace std; // 獲取驅(qū)動器數(shù)量 int GutDrivesCount() { DWORD drivers; int count = 0; //獲取驅(qū)動器數(shù) drivers = GetLogicalDrives(); while (drivers != 0) { if (drivers & 1 != 0) { count++; } drivers >>= 1; } return count; } // 獲取驅(qū)動器類型 std::string GetDrivesType(const char* lpRootPathName) { UINT uDriverType = GetDriveType(lpRootPathName); switch (uDriverType) { case DRIVE_UNKNOWN: return "未知類型"; break; case DRIVE_NO_ROOT_DIR: return "路徑無效"; break; case DRIVE_REMOVABLE: return "可移動磁盤"; break; case DRIVE_FIXED: return "固定磁盤"; break; case DRIVE_REMOTE: return "網(wǎng)絡磁盤"; break; case DRIVE_CDROM: return "光驅(qū)設備"; break; case DRIVE_RAMDISK: return "內(nèi)存映射盤"; break; default: break; } return "錯誤參數(shù)"; } // 獲取盤符容量 DriverInfo GetDrivesFreeSpace(const char* lpRootPathName) { // ULARGE_INTEGER 64位無符號整型值 ULARGE_INTEGER available, total, free; DriverInfo ref; // 獲取分區(qū)數(shù)據(jù)并返回DriversInfo結(jié)構(gòu)體 if (GetDiskFreeSpaceEx(lpRootPathName, (ULARGE_INTEGER*)&available, (ULARGE_INTEGER*)&total, (ULARGE_INTEGER*)&free)) { ref.total_space = ToGB(total); ref.free_space = ToGB(available); ref.available_space = ref.total_space - ref.free_space; } return ref; } std::vector<MyDriver> GetDriveForVector() { DWORD count = GutDrivesCount(); std::cout << "驅(qū)動器個數(shù): " << count << std::endl; DWORD dwSize = MAX_PATH; char szLogicalDrives[MAX_PATH] = { 0 }; // 獲取邏輯驅(qū)動器號字符串 DWORD dwResult = GetLogicalDriveStrings(dwSize, szLogicalDrives); // 處理獲取到的結(jié)果 if (dwResult > 0 && dwResult <= MAX_PATH) { // 定義兩個結(jié)構(gòu), MyDriver 臨時存儲單個結(jié)構(gòu),ref存儲所有磁盤的容器 MyDriver my_driver_ptr; std::vector<MyDriver> ref; // 從緩沖區(qū)起始地址開始 char* szSingleDrive = szLogicalDrives; while (*szSingleDrive) { // 邏輯驅(qū)動器類型 std::string type = GetDrivesType(szSingleDrive); // 獲取磁盤空間信息并存入 DriverInfo 結(jié)構(gòu) DriverInfo ptr; ptr = GetDrivesFreeSpace(szSingleDrive); // 填充結(jié)構(gòu)數(shù)據(jù) strcpy(my_driver_ptr.driver_name, szSingleDrive); strcpy(my_driver_ptr.driver_type, type.c_str()); my_driver_ptr.total_space = ptr.total_space; my_driver_ptr.free_space = ptr.free_space; my_driver_ptr.available_space = ptr.available_space; // 加入到容器中 ref.push_back(my_driver_ptr); /* std::cout << "盤符: " << szSingleDrive << " 類型: " << type << " 總?cè)萘? " << ptr.total_space << " 可用空間: " << ptr.free_space << " 已使用: " << ptr.available_space << std::endl; */ // 獲取下一個驅(qū)動器號起始地址 szSingleDrive += strlen(szSingleDrive) + 1; } return ref; } } int main(int argc,char *argv[]) { std::vector<MyDriver> ptr = GetDriveForVector(); // 循環(huán)輸出vector容器 for (int x = 0; x < ptr.size(); x++) { std::cout << "盤符: " << ptr[x].driver_name << " 類型: " << ptr[x].driver_type << " 總?cè)萘? " << ptr[x].total_space << " 可用空間: " << ptr[x].free_space << " 已使用: " << ptr[x].available_space << std::endl; } std::system("pause"); return 0; }
實現(xiàn)磁盤格式化
如下代碼定義了一個函數(shù)FormatDisk
,用于格式化由指定為字符串的驅(qū)動器號標識的磁盤。該函數(shù)使用Shell2.dll
模塊中的SHFormatDrive()
這個未導出函數(shù)實現(xiàn)對特定磁盤的格式化。
FormatDisk函數(shù)采用std::string
參數(shù)strDisk
,該參數(shù)指定要格式化的磁盤的驅(qū)動器號。該函數(shù)首先使用LoadLibraryA
加載Shell32.dll
庫,然后使用GetProcAddress
檢索SHFormatDrive
函數(shù)的地址。使用控制臺應用程序的窗口句柄、要格式化的磁盤的驅(qū)動器ID(根據(jù)驅(qū)動器號計算)以及指定格式選項的標志來調(diào)用SHFormatDrive
函數(shù)。
#include <iostream> #include <string> #include <Windows.h> #include <ShlObj.h> #pragma comment(lib, "Shell32.lib") // 格式化磁盤 void FormatDisk(std::string strDisk) { HINSTANCE hInstance = ::LoadLibraryA("Shell32.dll"); if (NULL == hInstance) { return; } typedef DWORD(*PSHFORMATDRIVE)(HWND, UINT, UINT, UINT); PSHFORMATDRIVE SHFormatDrive = (PSHFORMATDRIVE)::GetProcAddress(hInstance, "SHFormatDrive"); if (NULL == SHFormatDrive) { return; } UINT uiID = strDisk[0] - 'A'; // 獲取控制臺程序窗口句柄 HWND hWnd = ::GetConsoleWindow(); SHFormatDrive((HWND)hWnd, uiID, 0xFFFF, 0x0001); ::FreeLibrary(hInstance); } int main(int argc, char* argv[]) { // 傳入磁盤 FormatDisk("D"); return 0; }
移除指定磁盤
如下代碼演示了如何通過 Windows API
移除指定的磁盤驅(qū)動器,包括移除盤符和卸載卷加載點。代碼首先定義了一個 DeleteVolume
函數(shù),接收一個指向字符串的指針,表示要刪除的磁盤驅(qū)動器的盤符。然后,函數(shù)將盤符轉(zhuǎn)換為設備名稱,使用 DefineDosDeviceA
函數(shù)將其從系統(tǒng)中移除。接著,函數(shù)使用 DeleteVolumeMountPointA
函數(shù)刪除卷加載點。最后,main
函數(shù)調(diào)用 DeleteVolume
函數(shù)四次,移除了 C:、D:、E:、F:
四個磁盤驅(qū)動器。
#include <iostream> #include <Windows.h> // 移除指定盤符 BOOL DeleteVolume(char* lpszDriver) { // 將盤符和Dos設備路徑移除 char szDeviceName[MAX_PATH] = { 0 }; strcpy(szDeviceName, lpszDriver); szDeviceName[2] = '\0'; if (!DefineDosDeviceA(DDD_REMOVE_DEFINITION, szDeviceName, NULL)) { return FALSE; } // 卸載卷加載點 if (!DeleteVolumeMountPointA(lpszDriver)) { return FALSE; } return TRUE; } int main(int argc, char *argv[]) { DeleteVolume((char*)"C:"); DeleteVolume((char *)"D:"); DeleteVolume((char*)"E:"); DeleteVolume((char*)"F:"); return 0; }
輸出磁盤分區(qū)表
如下代碼,用于讀取和分析Windows
系統(tǒng)上第一個物理硬盤的主引導記錄MBR
。代碼中定義了幾個數(shù)據(jù)結(jié)構(gòu)來表示MBR
及其組件,包括引導記錄、磁盤分區(qū)表和磁盤簽名,ShowMbr使用ReadFile
函數(shù)從硬盤讀取MBR
數(shù)據(jù),然后以十六進制格式逐字節(jié)打印MBR
數(shù)據(jù)。AnalysMbr函數(shù)提取并分析MBR
數(shù)據(jù),打印出引導記錄、磁盤簽名和分區(qū)表信息。
主函數(shù)中使用CreateFileA
打開第一個物理硬盤,使用ShowMbr
函數(shù)讀取MBR
數(shù)據(jù),使用AnalystMbr
函數(shù)分析MBR
數(shù)據(jù),然后使用CloseHandle
函數(shù)關(guān)閉文件句柄,此段代碼讀者在編譯時需采用64位模式編譯。
#include <iostream> #include <Windows.h> // 定義數(shù)據(jù)結(jié)構(gòu)體 #define BOOTRECORDSIZE 440 typedef struct _BOOTRECORD { unsigned char BootRecore[BOOTRECORDSIZE]; }BOOTRECORD, * PBOOTRECORD; #define DPTSIZE 64 typedef struct _DPT { unsigned char Dpt[DPTSIZE]; }DPT, * PDPT; #define DPTNUMBER 4 typedef struct _DP { unsigned char BootSign; // 引導標志 unsigned char StartHsc[3]; unsigned char PatitionType; // 分區(qū)類型 unsigned char EndHsc[3]; ULONG SectorsPreceding; // 本分去之前使用的扇區(qū)數(shù) ULONG SectorsInPatition; // 分區(qū)的總扇區(qū)數(shù) }DP, * PDP; typedef struct _MBR { BOOTRECORD BootRecord; // 引導程序 unsigned char ulSigned[4]; // windows磁盤簽名 unsigned char sReserve[2]; // 保留位 DPT Dpt; // 分區(qū)表 unsigned char EndSign[2]; // 結(jié)束標志 }MBR, * PMBR; void ShowMbr(HANDLE hFile, PMBR pMbr) { DWORD dwTemp = 0; ::ReadFile(hFile, (LPVOID)pMbr, sizeof(MBR), &dwTemp, NULL); for (int i = 0; i < 512; i++) { printf("%2x ", ((BYTE*)pMbr)[i]); if (0 == ((i + 1) % 16)) { printf("\r\n"); } else if (0 == ((i + 1) % 8)) { printf(" "); } } } void AnalysMbr(MBR Mbr) { printf("\r\n引導記錄:\r\n"); for (int i = 0; i < BOOTRECORDSIZE; i++) { printf("%2x ", Mbr.BootRecord.BootRecore[i]); if (0 == ((i + 1) % 16)) { printf("\r\n"); } else if (0 == ((i + 1) % 8)) { printf(" "); } } printf("\r\n磁盤簽名:\r\n"); for (int i = 0; i < 4; i++) { printf("%02x ", Mbr.ulSigned[i]); } printf("\r\n解析分區(qū)表:\r\n"); for (int i = 0; i < DPTSIZE; i++) { printf("%02x ", Mbr.Dpt.Dpt[i]); if (0 == ((i + 1) % 16)) { printf("\r\n"); } else if (0 == ((i + 1) % 8)) { printf(" "); } } printf("\r\n"); PDP pDp = (PDP) & (Mbr.Dpt.Dpt); for (int i = 0; i < DPTNUMBER; i++) { printf("引導標識:%02x ", pDp[i].BootSign); printf("分區(qū)類型:%02x ", pDp[i].PatitionType); printf("\r\n"); printf("本分區(qū)之前扇區(qū)數(shù):%d ", pDp[i].SectorsPreceding); printf("本分區(qū)的總扇區(qū)數(shù):%d", pDp[i].SectorsInPatition); printf("\r\n"); printf("該分區(qū)的大小:%f\r\n", (double)pDp[i].SectorsInPatition / 1024 / 1024 * 512 / 1024 / 1024); printf("\r\n"); } printf("結(jié)束標志:\r\n"); for (int i = 0; i < 2; i++) { printf("%02x ", Mbr.EndSign[i]); } printf("\r\n"); } int main(int argc, char* argv[]) { // 打開物理硬盤設備 HANDLE hFile = ::CreateFileA("\\\\.\\PhysicalDrive0", GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL); if (INVALID_HANDLE_VALUE == hFile) { return -1; } MBR Mbr = { 0 }; ShowMbr(hFile, &Mbr); AnalysMbr(Mbr); CloseHandle(hFile); return 0; }
到此這篇關(guān)于C/C++實現(xiàn)磁盤相關(guān)操作的示例代碼的文章就介紹到這了,更多相關(guān)C++磁盤內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C/C++實現(xiàn)矩陣的轉(zhuǎn)置(示例代碼)
C/C++實現(xiàn)矩陣的轉(zhuǎn)置(示例代碼)需要的朋友可以過來參考下,希望對大家有所幫助2013-10-10C++數(shù)據(jù)結(jié)構(gòu)之雙向鏈表
這篇文章主要為大家詳細介紹了C++數(shù)據(jù)結(jié)構(gòu)之雙向鏈表,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05實戰(zhàn)開發(fā)為單片機的按鍵加一個鎖防止多次觸發(fā)的細節(jié)
今天小編就為大家分享一篇關(guān)于實戰(zhàn)開發(fā)為單片機的按鍵加一個鎖防止多次觸發(fā)的細節(jié),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12C++字符數(shù)組、字符數(shù)組指針和string類
這篇文章主要介紹了C++字符數(shù)組、字符數(shù)組指針和string類,string是一個類而不是基本數(shù)據(jù)類型,數(shù)組不含有處理函數(shù),下面更多詳細內(nèi)容,需要的小伙伴可以參考下面文章2022-03-03