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……

       這個函數無參數,函數原型如下:

DWORD GetLogicalDrives(VOID);

代碼運行結果:

 

可以對應一下,確實是正確的。不過H位為0應該是因為這光驅中無光盤。/*此處錯誤,0對應的是I盤,時間久遠,估計是因為但是U盤被拔掉了。H盤位置對應的確實是1*/

 

GetLogicalDriveStrings

       這個函數還挺有意思的,可以用於獲取目前系統上所有的盤符,有趣就在於其字符串的排列方式。函數原型如下:

 

DWORD GetLogicalDriveStrings(  DWORD nBufferLength,  // size of buffer

                                                      LPTSTR lpBuffer       // drive strings buffer);

       然后看下函數調用后其在緩沖區參數的結果:

 

       很有趣吧,哈哈,反正我是第一次見到。

       然后下面展示下這個字符串是如何結束的:

 

       最后面連續的兩個0值表明字符串都已結束。好玩的很。

 

FindFirstVolume

       這個函數能獲取計算機上的第一個卷,並且返回一個句柄,用於FindNextVolume函數的使用。函數原型如下:

HANDLE FindFirstVolume(  LPTSTR lpszVolumeName,   // output buffer

DWORD cchBufferLength    // size of output buffer);

演示結果:

      

這個函數我在使用的時候還遇到了一點小小的麻煩,就是最初我設置緩沖區大小為32,結果,返回了一個無效句柄……后來改的256,才正常工作了。

 

FindNextVolume

       這個函數時要配合着上面函數返回的句柄使用的函數,函數原型如下:

       BOOL FindNextVolume(  HANDLE hFindVolume,      // volume search handle

            LPTSTR lpszVolumeName,   // output buffer

            DWORD cchBufferLength    // size of output buffer);

貼下運行截圖:

 

在這里你可能要問,上面這一串數據都是什么,我的回答:我也不知道。

FindVolumeClose

這個函數的作用就是單純的關閉上面那個查找句柄的。不多說了。

GetDriveType

這個函數的作用是根據盤符來確定驅動器的類型。且看函數原型如下:

UINT GetDriveType(  LPCTSTR lpRootPathName   // 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:\。演示下運行結果:

 

這個函數沒大多好說的,看了就會用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM