使用C/C++中的stdio文件操作时如何检测磁盘空间不足?

5
我正在制作一个小程序,如下所示:

我正在制作一个小程序,如下所示:

void reserve_file_space(char* file_path, size_t amount)
{
    FILE* fp = fopen(file_path, "w+b");
    if(!fp)
    {
        printf("could not create a new file\n");
        return;
    }

    int fseek_ret = fseek(fp, amount, SEEK_SET);
    if(fseek_ret != 0)
    {
        printf("could not seek to the desired position\n");
        fclose(fp);
        return;
    }

    char garbage = 1;
    size_t ret = fwrite(&garbage, 1, 1, fp);
    if(ret != 1)
    {
        printf("could not write the garbage character\n");
    }

    fclose(fp);
}

int main(int argc, char* argv[])
{
    reserve_file_space("C:\\Users\\SysPart\\Desktop\\test.bin", 1 << 30);
    return 0;
}

我的PC剩余的磁盘空间约为500 MB。在main()中,如果我调用reserve_file_space("C:\\Users\\SysPart\\Desktop\\test.bin", 1 << 28 /*256 MB*/);,它将创建一个精确大小为256 MB的文件。但是,如果我调用reserve_file_space("C:\\Users\\SysPart\\Desktop\\test.bin", 1 << 30 /*1 GB*/);则会生成大小为0的输出文件,并且不打印任何错误通知。
如何学习磁盘空间是否足够处理正确?

3
首要步骤是检查fseek和甚至fclose的返回值。 - kaylum
@kaylum 我试过了,两次调用都返回了0。 - duong_dajgja
@kaylum 检查 fclose 的返回值是有意义的。谢谢! - duong_dajgja
1个回答

3
我该如何确定磁盘空间是否足够正确处理?
标准库中没有此类功能。向前寻找(就像您所做的那样)不能保证失败,因为文件系统可以延迟分配磁盘空间,直到实际需要该空间(因为您正在写入数据)。您只写了一个字符,因此此时实际上只需要这一个字符的空间(以及一些元信息)。
要确保有足够的空间(即使考虑到在您检查后可能占用空间的其他进程),您必须编写所需大小的随机数据,然后用实际数据覆盖它-这不是一种有效的方法。
标准做法是尝试写入(无需预分配),并检查该写入操作是否成功。这也避免了进程终止留下一些“预留”但无用的文件。
要事先检查可用磁盘空间,您必须依赖于特定于操作系统的功能。
对于POSIX系统,有statvfs()

对于WinAPI,有GetDiskFreeSpace()


1
但是,像往常一样检查是否有足够的空间,然后执行操作会创建竞争条件,因为另一个程序可能已经在你之前使用了可用空间。请参阅此帖子以获取Windows的解决方案,以预分配空间而无需写入文件。 - RedX
抱歉,我错过了括号中非常重要的句子。我提供的链接是一篇详细介绍如何在Windows下保留空间而无需写入文件的帖子。我试图在我的第一条评论中澄清这一点。 - RedX
@DavidC.Rankin:由于文件系统可能会进行压缩,并且还有其他进程一直在使用和释放磁盘空间,所以你最多只能得到一个粗略的猜测... - DevSolar
底线是——尝试编写代码,检查结果。 - DevSolar
1
@duong_dajgja:我没有提到Boost,因为你标记了问题“C”。但是,是的,那是一个方便的包装器,用于OS特定的函数...带有它们所有的缺点。 - DevSolar
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接