GetFreeDiskSpaceEx如何返回(看似)错误的磁盘空间量?

时间:2012-01-24 20:07:18

标签: c++ windows winapi diskspace

所以我在一台输出大图像的设备上工作(从30MB到2GB +)。在我们开始创建其中一个映像之前,我们通过GetDiskFreeSpaceEx检查是否有足够的磁盘空间。通常(在这种情况下)我们写入同一网络上的共享文件夹。磁盘空间上没有用户配额。

昨晚,在准备演示时,我们开始试运行。在运行期间,我们遇到了故障。我们需要327391776字节,并被告知我们只有186580992可用。来自GetDiskFreeSpaceEx的数字是:

  

可用的免费空间:186580992

     

可用空间总面积:186580992

这些变量对应于两个(输出)参数QuadPartlpFreeBytesAvailablelpTotalNumberOfFreeBytes中的GetDiskFreeSpaceAvailable变量。

此代码已使用多年,我从未见过假阴性。这是完整的功能:

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可用空间,远远超过报告的数量。再次开始测试后,没有改变任何工作。

所以我的问题是;什么可能导致这样的事情?据我所知,这不是一个编程错误,正如我前面提到的,这段代码已经使用了很长时间而没有任何问题。

我检查了远程机器的事件日志,发现失败时没有任何兴趣。我希望之前有人见过类似的东西,提前谢谢。

1 个答案:

答案 0 :(得分:3)

可能没有任何用处,但是“奇怪”:

177GB~ = 186580992 * 1000。

这可以通过代码中其他地方发生的堆栈损坏(因为您没有初始化本地变量)来解释。

代码“inRequestedSize / compressionRatio”不必使用float进行除法,并且由于你已经使用强制转换静态“转换松散精度”警告,你实际上也可能遇到错误(但是数字在示例中给出应该工作)。你可以简单地做“inRequestedSize / 10”。

最后但并非最不重要的是,您没有说明代码的运行位置。在Mobile上,GetDiskFreeSpaceEx的文档声明:

  

启用移动加密后,此功能的报告行为会发生变化。每个加密文件至少有一个4 KB的开销页面。此功能在报告可用空间量时会考虑此开销。也就是说,如果128 KB磁盘包含单个60 KB文件,则此函数报告64 KB可用,减去文件及其相关开销占用的空间。

     

虽然此功能报告总可用空间,但在估计多个新文件是否适合剩余空间时,请记住加密文件的空间要求。启用Mobile Encryption时,包括开销所需的空间量。每个文件至少需要4 KB。例如,单个60 KB文件需要64 KB,但是两个30 KB文件实际需要68 KB。