【发布时间】:2023-04-01 00:18:01
【问题描述】:
所以我在一个输出大图像(从 30MB 到 2GB+)的设备上工作。在我们开始创建这些映像之一之前,我们通过GetDiskFreeSpaceEx 检查是否有足够的磁盘空间。通常(在这种情况下)我们正在写入同一网络上的共享文件夹。磁盘空间上没有用户配额。
昨晚,为了准备演示,我们开始了试运行。在运行过程中,我们遇到了失败。我们需要327391776 字节,并被告知我们只有186580992 可用。 GetDiskFreeSpaceEx 的数字是:
用户可用空间:186580992
总可用空间:186580992
这些对应于lpFreeBytesAvailable 和lpTotalNumberOfFreeBytes 到GetDiskFreeSpaceAvailable 的两个(输出)参数中的QuadPart 变量。
此代码已使用多年,我从未见过假阴性。这是完整的功能:
long IsDiskSpaceAvailable( const char* inDirectory,
const _int64& inRequestedSize,
_int64& outUserFree,
_int64& outTotalFree,
_int64& outCalcRequest )
{
ULARGE_INTEGER fba;
ULARGE_INTEGER tnb;
ULARGE_INTEGER tnfba;
ULARGE_INTEGER reqsize;
string dir;
size_t len;
dir = inDirectory;
len = strlen( inDirectory );
outUserFree = 0;
outTotalFree = 0;
outCalcRequest = 0;
if( inDirectory[len-1] != '\\' )
dir += "\\";
// this is the value of inRequestSize that was passed in
// inRequestedSize = 3273917760;
if( GetDiskFreeSpaceEx( dir.c_str(), &fba, &tnb, &tnfba ) )
{
outUserFree = fba.QuadPart;
outTotalFree = tnfba.QuadPart;
// this is computed dynamically given a specific compression
// type, but for simplicity I had hard-coded the value that was used
float compressionRatio = 10.0;
reqsize.QuadPart = (ULONGLONG) (inRequestedSize / compressionRatio);
outCalcRequest = reqsize.QuadPart;
// this is what was triggered to cause the failure,
// i.e., user free space was < the request size
if( fba.QuadPart < reqsize.QuadPart )
return( RetCode_OutOfSpace );
}
else
{
return( RetCode_Failure );
}
return( RetCode_OK );
}
因此,3273917760 的值被传递给函数,这是压缩前所需的磁盘空间总量。该函数将其除以10 的压缩比,得到所需的实际大小。
当我检查共享所在的磁盘时,它有大约 177GB 的可用空间,远远超过所报告的。再次开始测试后没有改变任何工作。
所以我的问题是;什么可能导致这样的事情?据我所知,这不是编程错误,而且正如我之前提到的,这段代码已经使用了很长时间,没有任何问题。
我检查了远程机器的事件日志,在发生故障的时候没有发现任何有趣的东西。我希望有人以前见过类似的东西,在此先感谢。
【问题讨论】:
-
可能在您遇到故障的那一刻磁盘空间较小。例如,备份进程(或恶意软件扫描程序)可能保留了一堆磁盘空间,然后在完成后再次释放。
-
@AdrianMcCarthy:谢谢阿德里安。这是我希望在事件日志中找到的那种东西,但如果有类似的事情发生,它就不会被记录下来。我正在努力想出一个解释,但我找不到任何有趣的证据。
-
您认为问题可能是整数签名问题吗? GetDiskFreeSpaceEx 的返回值是一个无符号整数 (ULONGLONG),它是 'typedef'ed 到 'unsigned __int64'。通过将其视为有符号值(即通过您的返回值),您不会将其可以存储的数量减半吗?
-
@AdrianConlon:是的,是的,但看起来它仍然是 2^63,我认为我不必担心一段时间。
标签: c++ windows winapi diskspace