windows磁碟相關API實踐說明
API的列表如下,網上找的,我覺得還是蠻詳細的:
磁碟和驅動器管理API
GetLogicalDrivers 獲取主機中所有的邏輯驅動器,以BitMap的形式返回.
GetLogicalDriverString 獲取主機中所有的邏輯驅動器,以驅動器根路徑字串返回.
FindFirstVolume 查詢主機中的第一個驅動器,返回查詢控制代碼.
FindNextVolume 根據FindFirstVolume返回控制代碼,查詢主機中後繼的邏輯驅動器
FindVolumeClose 關閉驅動器查詢控制代碼
GetDriveType 獲取驅動器型別
GetVolumeInformation 獲取邏輯驅動器資訊
FindFirstVolumeMountPoint查詢指定卷的第一個掛載點,返回查詢控制代碼
FindNextVolumeMountPoint根據FindFirstVolumeMountPoint返回的控制代碼,查詢卷的後繼掛載點.
FindVolumeMountPointClose關閉掛載點查詢控制代碼
GetVolumeNameForVolumeMountPoint根據指定掛載點獲取相應的卷裝置名
SetVolumeMountPoint 將指定卷掛載到指定掛載點處
GetDiskFreeSpace 獲取磁碟空間資訊,包括每簇的扇區數,每扇區的位元組數,簇數量,空閒的簇數量
GetDiskFreeSpaceEx 獲取使用者可用的空閒空間的位元組數,磁碟總容量的位元組數
檔案和目錄管理API
DeleteFile 刪除引數所指定檔案
CopyFile 複製指定檔案為一個新檔案
MoveFile 將指定檔案或目錄移動到指定位置
CreateFile 新建或開啟一個檔案,獲取檔案控制代碼
ReadFile 讀取由檔案控制代碼指定檔案的內容
WriteFile 向由檔案控制代碼指定的檔案中寫入內容
GetFileSize 獲取檔案大小,返回DWORD中;大小超出DWORD最大值時可指定高32位的DWORD聯合儲存
GetFileSizeEx 獲取檔案大小,儲存到一個64位的大整數聯合體中.
CreateDirectory 建立一個目錄
GetCurrentDirectory 獲取當前程式所在目錄
SetCurrentDirectory 設定當前程式所在目錄
GetModuleFileName 獲取當前模組全路徑
FindFirstFile 查詢指定目錄下第一個檔案控制代碼或目錄,獲得查詢控制代碼
FindNextFile 根據FindFirstFile獲得的控制代碼,迴圈查詢檔案或目錄
GetFileAttributes 獲取指定檔案目錄屬性,返回一個DWORD值
GetFileAttributesEx 獲取檔案或目錄屬性,儲存在WIN32_FILE_ATTRIBUTE_DATA結構體中
SetFileAttributes 將檔案屬性設定為指定值
FileTimeToLocalFileTime 將檔案時間轉換為本地時間
FileTimeToSystemTime 將檔案轉換為系統時間,SYSTEMTIME格式便於顯示
高階檔案操作
CreateFileMapping 建立檔案的對映物件
MapViewOfFile 建立檢視,將建立的檔案對映物件對映到當前程序的地址空間中
FlushViewOfFile 將檢視中的資料都寫入磁碟,對檢視的操作都會反映到磁碟上的檔案中
OpenFileMapping 開啟已經存在的命名的檔案對映物件
UnmapViewOfFile 取消檔案對映
GetMappedFileName 從對映物件獲取被對映檔案的檔案裝置名
QueryDosDevice 獲取MS-DOS裝置名
GetLocalDrivers
最近真的是發現做文件也是一種習慣啊。慢慢來吧。
第一個函式GetLocalDrivers這個函式的返回值是一個DWORD,也就是以Bitmap形式返回相關的資訊,從0位開始為A盤,從以往後遞迴就是BCD……
這個函式無引數,函式原型如下:
DWORDGetLogicalDrives(VOID);
程式碼執行結果:
可以對應一下,確實是正確的。不過H位為0應該是因為這光碟機中無光碟。/*此處錯誤,0對應的是I盤,時間久遠,估計是因為但是U盤被拔掉了。H盤位置對應的確實是1*/
GetLogicalDriveStrings
這個函式還挺有意思的,可以用於獲取目前系統上所有的碟符,有趣就在於其字串的排列方式。函式原型如下:
DWORD GetLogicalDriveStrings( DWORD nBufferLength, // size of buffer
LPTSTRlpBuffer // drive strings buffer);
然後看下函式呼叫後其在緩衝區引數的結果:
很有趣吧,哈哈,反正我是第一次見到。
然後下面展示下這個字串是如何結束的:
最後面連續的兩個0值表明字串都已結束。好玩的很。
FindFirstVolume
這個函式能獲取計算機上的第一個卷,並且返回一個控制代碼,用於FindNextVolume函式的使用。函式原型如下:
HANDLE FindFirstVolume( LPTSTR lpszVolumeName, // output buffer
DWORD cchBufferLength // size of output buffer);
演示結果:
這個函式我在使用的時候還遇到了一點小小的麻煩,就是最初我設定緩衝區大小為32,結果,返回了一個無效控制代碼……後來改的256,才正常工作了。
FindNextVolume
這個函式時要配合著上面函式返回的控制代碼使用的函式,函式原型如下:
BOOLFindNextVolume( HANDLE hFindVolume, // volume search handle
LPTSTR lpszVolumeName, // output buffer
DWORD cchBufferLength // size of output buffer);
貼下執行截圖:
在這裡你可能要問,上面這一串資料都是什麼,我的回答:我也不知道。
FindVolumeClose
這個函式的作用就是單純的關閉上面那個查詢控制代碼的。不多說了。
GetDriveType
這個函式的作用是根據碟符來確定驅動器的型別。且看函式原型如下:
UINTGetDriveType( LPCTSTRlpRootPathName // root directory);
這裡引數是就是路徑名,當然了,只有一個碟符,如CDEF,這個引數可以通過上面的一個函式GetLogicalDriveString的結果來使用。返回值就是驅動器型別了。型別表如下:
我寫了個專用函式,如下:
1 //僅?限T單Ì£¤線?程¨¬使º1用®? 2 3 LPCTSTR GetTypeString(LPCTSTR lpDriverRoot) 4 5 { 6 7 static LPCTSTR Buf[7] = \ 8 9 { 10 11 _T("UNKNOWN"), 12 13 _T("NO_ROOT_DIR"), 14 15 _T("REMOVABLE"), 16 17 _T("FIXED"), 18 19 _T("REMOTE"), 20 21 _T("CDROM"), 22 23 _T("RAMDISK"), 24 25 }; 26 27 int nAddr = -1; 28 29 switch(GetDriveType(lpDriverRoot)) 30 31 { 32 33 case DRIVE_UNKNOWN: 34 35 nAddr = 0; 36 37 break; 38 39 case DRIVE_NO_ROOT_DIR: 40 41 nAddr = 1; 42 43 break; 44 45 case DRIVE_REMOVABLE: 46 47 nAddr = 2; 48 49 break; 50 51 case DRIVE_FIXED: 52 53 nAddr = 3; 54 55 break; 56 57 case DRIVE_REMOTE: 58 59 nAddr = 4; 60 61 break; 62 63 case DRIVE_CDROM: 64 65 nAddr = 5; 66 67 break; 68 69 case DRIVE_RAMDISK: 70 71 nAddr = 6; 72 73 break; 74 75 default: 76 77 return NULL; 78 79 } 80 81 return Buf[nAddr]; 82 83 }
執行結果:
這裡截圖只有一部分,顯示了磁碟和光碟的區別。
GetVolumeInformation
這個函式還是比較複雜的,無他,引數太多了,且看函式原型:
BOOL GetVolumeInformation( LPCTSTR lpRootPathName, // root directory
LPTSTR lpVolumeNameBuffer, // volume name buffer
DWORD nVolumeNameSize, // length of name buffer
LPDWORD lpVolumeSerialNumber, // volume serial number
LPDWORD lpMaximumComponentLength, // maximum file name length
LPDWORD lpFileSystemFlags, // file system options
LPTSTR lpFileSystemNameBuffer, // file system name buffer
DWORD nFileSystemNameSize // length of file system name buffer);
一共8個引數,真要命。
這個函式的作用是用來獲取指定路徑的檔案系統以及卷資訊q其中有五個引數都是輸出型引數。下面看下兩個NameBuffer都返回的是什麼。
這裡看到lpVolumeNameBuffer引數返回的是驅動器的名字,這裡系統盤是win7,而其他盤因為未命名所以什麼也沒有。
lpFileSystemNameBuffer引數則是用於返回檔案系統型別。這裡能看到,硬碟的檔案系統是NTFS。後面因為我的筆記本中插著U盤,所以其 顯示結果是FAT32.
而lpVolumeSerialNumber引數返回的是序列號,這個引數具體的用處我也不是很清楚。
lpMaximumComponentLength引數返回的是檔案系統支援的檔名最大長度。255還是很大的。
lpFileSystemFlags檔案系統選項的標誌位,還是所謂的文圖返回吧。這個引數有個專門的列表:
這種表就屬於那種一看就頭大的表,還是寫個函式看一下比較靠譜。
函式實現:
1 void CheckFileSystemFlag(DWORD FSF) 2 { 3 //我是不是應該用個結構體做? 4 static LPCTSTR lpList[12] = 5 { 6 _T("The file system preserves the case of file names when it places a name on disk."), 7 _T("The file system supports case-sensitive file names."), 8 _T("The file system supports Unicode in file names as they appear on disk."), 9 _T("The file system preserves and enforces ACLs. For example, NTFS preserves and enforces ACLs, and FAT does not."), 10 _T("The file system supports file-based compression."), 11 _T("The specified volume is a compressed volume; for example, a DoubleSpace volume."), 12 _T("The file system supports named streams."), 13 _T("The file system supports the Encrypted File System (EFS)."), 14 _T("The file system supports object identifiers."), 15 _T("The file system supports reparse points."), 16 _T("The file system supports sparse files."), 17 _T("The file system supports disk quotas.") 18 }; 19 static const DWORD FlagList[12] = 20 { 21 FS_CASE_IS_PRESERVED, 22 FS_CASE_SENSITIVE, 23 FS_UNICODE_STORED_ON_DISK, 24 FS_PERSISTENT_ACLS, 25 FS_FILE_COMPRESSION, 26 FS_VOL_IS_COMPRESSED, 27 FILE_NAMED_STREAMS, 28 FILE_SUPPORTS_ENCRYPTION, 29 FILE_SUPPORTS_OBJECT_IDS, 30 FILE_SUPPORTS_REPARSE_POINTS, 31 FILE_SUPPORTS_SPARSE_FILES, 32 FILE_VOLUME_QUOTAS 33 }; 34 for(int i = 0;i < 12;++ i) 35 { 36 if(FSF & FlagList[i]) 37 wcout << lpList[i] << endl; 38 } 39 }
可以對照一下結果,能發現,NTFS僅僅沒有壓縮卷這一項。而FAT32則只有兩個結果。檔案系統的差別還是挺大的。
FindFirstVolumeMountPoint
這個函式的原型如下:
HANDLE FindFirstVolumeMountPoint( LPTSTR lpszRootPathName, // volume name
LPTSTR lpszVolumeMountPoint, // output buffer
DWORD cchBufferLength // size of output buffer);
這裡第一個引數是使用FindFirstVolume的的volume字串,也就是很長的那一串。但是在我的計算機上,這個函式的返回值始終都是失敗,而且現在也沒理解所謂的掛載是什麼意思。這幾個函式暫且擱置。
GetDiskFreeSpace
這個函式是用來獲取磁碟資訊的。函式原型如下:
BOOL GetDiskFreeSpace( LPCTSTR lpRootPathName, // root path
LPDWORD lpSectorsPerCluster, // sectors per cluster
LPDWORD lpBytesPerSector, // bytes per sector
LPDWORD lpNumberOfFreeClusters, // free clusters
LPDWORD lpTotalNumberOfClusters // total clusters);
第一個引數就是路徑名,比如C:\。演示下執行結果:
這個函式沒大多好說的,看了就會用。