以下是關于MSDN中的有關詳細說明:對于大于的2G分區,GetDiskFreeSpace函數可能(什么可能,是一定!)返回錯誤的值,此時函數會屏蔽存在lpNumberOfFreeClusters及lpTotalNumberOfClusters中的值,因此建議不要用該函數來獲得大于2G分區的信息。對于大于2G的分區應當使用GetDiskFreeSpaceEx函數(從Win95OEMOSR2開始),此函數可以返回分區的有關正確信息。
找到了問題所在便可以對癥下藥了,即用GetDiskFreeSpaceEx函數代替GetDiskFreeSpace函數即可。以下是GetDiskFreeSpaceEx函數中所要傳遞增的參數
 lpRootPathNameString ,不包括卷名的磁盤根路徑名
lpFreeBytesAvailableToCallerLARGE_INTEGER,指定一個變量,用于容納調用者可用的字節數量
lpTotalNumberOfBytesLARGE_INTEGER ,指定一個變量,用于容納磁盤上的總字節數
lpTotalNumberOfFreeBytesLARGE_INTEGER,指定一個變量,用于容納磁盤上可用的字節數
PrivateTypeLARGE_INTEGER
 lowpartAsLong
 highpartAsLong
EndType
我們可以看到LARGE_INTEGER是一個由兩個long型組成的一個類型,兩個long組成表示的都是無符號的數,在轉換時應當定義一個single型的變量,使其等于highpart*(2^32-1) lowpart,注意此處的兩個long型相當于C/C 中的無符號型整數類型,因為在VB中不存在此種類型,故而在換算時要處理好轉換關系。我本人的做法是首先判斷long型變量的正負,如是正直接相乘,如是負則用2^32-1減去該值再相乘(具體算法詳見下面的代碼)。
OptionExplicit
PrivateTypeLARGE_INTEGER
 lowpartAsLong
 highpartAsLong
EndType
PrivateDeclareFunctionGetDiskFreeSpaceLib"kernel32"Alias"GetDiskFreeSpaceA"(ByVallpRootPathNameAsString,lpSectorsPerClusterAsLong,lpBytesPerSectorAsLong,lpNumberOfFreeClustersAsLong,lpTotalNumberOfClustersAsLong)AsLong
PrivateDeclareFunctionGetDiskFreeSpaceExLib"kernel32"Alias"GetDiskFreeSpaceExA"_
(ByVallpRootPathNameAsString,lpFreeBytesAvailableToCallerAsLARGE_INTEGER,_
lpTotalNumberOfBytesAsLARGE_INTEGER,lpTotalNumberOfFreeBytes_
AsLARGE_INTEGER)AsLong
PrivateSubCommand1_Click()
 DimlngSectors&
 DimlngTotalCluster&
 DimlngFreeCluster&
 DimlngPerCluster&
 DimlngperBytes&
 DimlngSize#
 GetDiskFreeSpace"c:/",lngPerCluster,lngperBytes,lngFreeCluster,lngTotalCluster
 MsgBoxCStr(lngTotalCluster*lngperBytes*lngPerCluster)
 Debug.PrintlngTotalCluster,lngperBytes,lngPerCluster
EndSub
PrivateTypeLARGE_INTEGER
 lowpartAsLong
 highpartAsLong
EndType
PrivateDeclareFunctionGetDiskFreeSpaceLib"kernel32"Alias"GetDiskFreeSpaceA"(ByVallpRootPathNameAsString,lpSectorsPerClusterAsLong,lpBytesPerSectorAsLong,lpNumberOfFreeClustersAsLong,lpTotalNumberOfClustersAsLong)AsLong
PrivateDeclareFunctionGetDiskFreeSpaceExLib"kernel32"Alias"GetDiskFreeSpaceExA"_
(ByVallpRootPathNameAsString,lpFreeBytesAvailableToCallerAsLARGE_INTEGER,_
lpTotalNumberOfBytesAsLARGE_INTEGER,lpTotalNumberOfFreeBytes_
AsLARGE_INTEGER)AsLong
PrivateSubCommand1_Click()
注釋:用GetDiskFreeSpace得到錯誤的容量
 DimlngSectors&
 DimlngTotalCluster&
 DimlngFreeCluster&
 DimlngPerCluster&
 DimlngperBytes&
 DimlngSize#
 GetDiskFreeSpace"c:/",lngPerCluster,lngperBytes,lngFreeCluster,lngTotalCluster
 MsgBoxCStr(lngTotalCluster*lngperBytes*lngPerCluster)
EndSub
PrivateSubcmdStart_Click()
注釋:用GetDiskFreeSpaceEx得到正確的容量
 DimlngFreeCallerAsLARGE_INTEGER
 DimlngTotalAsLARGE_INTEGER
 DimlngTotalFreeAsLARGE_INTEGER
 DimsngSize#
 GetDiskFreeSpaceEx"c:/",lngFreeCaller,lngTotal,lngTotalFree
注釋:以下用來顯示出分區總容量(以G為單位)
 MsgBoxGetSize(lngTotal)/2^30
EndSub
PrivateFunctionGetSize(lngSizeAsLARGE_INTEGER)AsSingle
注釋:用來從LARGE_INTEGER型變量中換算出實際的大小
WithlngSize
 If.highpart<0Then
  GetSize=(2^32-1-.highpart)*(2^32-1)
 Else
  GetSize=.highpart*(2^32-1)
 EndIf
 If.lowpart<0Then
  GetSize=GetSize (2^32-1-.lowpart)
 Else
  GetSize=GetSize .lowpart
 EndIf
EndWith
EndFunction
PrivateFunctionGetSize(lngSizeAsLARGE_INTEGER)AsSingle
 注釋:用來從LARGE_INTEGER型變量中換算出實際的大小
 WithlngSize
  If.highpart<0Then
   GetSize=(2^32-1-.highpart)*(2^32-1)
  Else
   GetSize=.highpart*(2^32-1)
  EndIf
  If.lowpart<0Then
   GetSize=GetSize (2^32-1-.lowpart)
  Else
   GetSize=GetSize .lowpart
  EndIf
 EndWith
EndFunction
從LARGE_INTEGER的定義來看,應用此函數理論上可得到2^64/2^30=2^34G的分區的大小,不知這輩子能否用上這么大的硬盤.
->新聞熱點
疑難解答