2010-10-10 84 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; 
} 
相关问题