2010-10-10 28 views
5

我在寫一個跨平臺的應用程序,我需要可用的磁盤空間。對於posix系統(Linux和Macos),我使用statvfs。我創建了這個C++方法:如何獲取Posix系統中的可用磁盤空間總量?

long OSSpecificPosix::getFreeDiskSpace(const char* absoluteFilePath) { 
    struct statvfs buf; 

    if (!statvfs(absoluteFilePath, &buf)) { 
     unsigned long blksize, blocks, freeblks, disk_size, used, free; 
     blksize = buf.f_bsize; 
     blocks = buf.f_blocks; 
     freeblks = buf.f_bfree; 

     disk_size = blocks*blksize; 
     free = freeblks*blksize; 
     used = disk_size - free; 

     return free; 
    } 
    else { 
     return -1; 
    } 
} 

不幸的是我收到了很奇怪的值,我不明白。例如: f_blocks = 73242188 f_bsize = 1048576 f_bfree = 50393643 ...

是在比特,字節或任何其他的價值?我讀到這裏的計算器這些應該是字節,但我會得到免費的字節總數爲: f_bsize * f_bfree = 1048576 * 50393643 但這意味着49212.542GB ...太多...

上午我在代碼或其他方面做錯了什麼? 謝謝!

+0

你使用哪個文件系統,塊大小爲1048576? – 2010-10-10 10:21:47

+0

這是一個Mac OS擴展(區分大小寫,日誌式)。現在我正在使用mac,但據我所知,這應該是可行的。 – 2010-10-10 10:30:50

+0

除了塊大小和所謂的70TB驅動器的奇怪之處 - 請注意,32位OSX上的「長」只有32位。即使你有正確的數字,這可能足夠大的數量的*塊*,但不夠大的數量的*字節*。驅動器大小可達4GB,可從專業供應商處獲得;-) – 2010-10-10 13:18:43

回答

2

我想最後兩個答案是正確和有用的。不過,我通過簡單地用功能statfs替換功能statvfs解決。如預期的塊大小然後是4096,並且一切似乎是正確的。 謝謝!

+1

'statfs'已棄用。 – 2012-09-08 03:49:19

+0

我無法在OS X上看到'statfs'在哪裏被棄用。另外'statfs'會產生正確的值。 – codingFriend1 2012-09-12 08:22:35

+0

我也看不到:https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man2/statfs.2.html。 – 2012-09-12 08:31:26

8

我不知道OSX不夠好預測這肯定是答案,但f_blocksf_bfree實際上是指「基本塊」或「片段」(這是大小的buf.f_frsize字節),而不是「文件系統塊大小」(這是buf.f_bsize字節):

http://www.opengroup.org/onlinepubs/009695399/basedefs/sys/statvfs.h.html

f_bsize僅是一種暗示的首選大小是做什麼用的I/O操作,它不一定是什麼做的文件系統是如何劃分的。

3

下列行:

disk_size = blocks*blksize; 
free = freeblks*blksize; 

具有HUGE HDS時會引起溢流。

我得到了奇怪的結果,直到我想出我的高清是455GiB,請考慮鑄造塊,blksize和freeblks vars無符號長乘以前很長時間。

事情是這樣的:

unsigned long long disk_size = (unsigned long long) (blocks) * (unsigned long long) (blksize) 

我見過很多類似這樣的問題,但沒有人注意到這一點的答案。

+0

好抓!我也看到了奇怪的數字(無符號long long) – lppier 2015-04-17 06:52:02

1
uint64_t userAvailableFreeSpace() 
{ 
    struct statvfs stat; 
    struct passwd *pw = getpwuid(getuid()); 
    if (NULL != pw && 0 == statvfs(pw->pw_dir, &stat)) 
    { 
     uint64_t freeBytes = (uint64_t)stat.f_bavail * stat.f_frsize; 
     return freeBytes; 
    } 
    return 0ULL; 
} 
相關問題