当增强的内存映射文件分配更多的磁盘空间时,如何检测到错误比硬盘上的空闲

在我的build模代码中,我使用boost 内存映射文件来分配磁盘上的大数组。

它运作良好,但我无法find一种方式来检测我分配磁盘驱动器上的空闲空间大于数组的情况。 例如下面的代码将会愉快地执行(假设我在硬盘上的可用空间less于8E9字节):

boost::iostreams::mapped_file_params file_params; file_params.path = path; file_params.mode = std::ios::in | std::ios::out; file_params.new_file_size = static_cast<size_t>(8E9); # About 10GB file_params.length = static_cast<size_t>(8E9); boost::iostreams::mapped_file result; result.open(file_params); 

我甚至可以在resuld.data()上工作,直到我写入部分未分配的内存(因为HDD上缺less空间),然后出现以下错误:

  memory access violation at address: 0x7e9e2cd1e000: non-existent physical address 

有没有什么办法来检测这个错误之前,我得到神秘的memory access violation

我实际上testing了这一点:如果文件比分区上的avilable可用空间大,则代码具有内存访问冲突,如果代码更小(我通过更改分区上的空间而不是通过编辑代码来testing它)。

可能的解决scheme

如果我std:fill用零std:fill文件内容我仍然得到memory access violation ,但这个错误位于分配附近,更容易debugging。 我宁愿要某种方式来引发exception。

您可以使用fallocateposix_fallocatefallocate为文件预留空间。 这样你就知道你永远不会“过度犯下”了。 它有一个性能上的缺点,当然在初始创建时。

出于安全原因,操作系统可能fallocate上的块fallocate

fallocate可以让你做不成文的范围,但它在第一次访问时仍然是零。 在Windows上,这可以使用, SetFileValidData让你绕过即使。

请注意,使用O_DIRECT + fallocate() Linux仍然使用相当多的CPU(而不是Windows的SetFileValidData ),尽管IO带宽通常是瓶颈,但是如果您同时在做大量的CPU工作,这仍然会带来明显的性能影响。

有没有什么办法来检测这个错误之前,我得到神秘的内存访问冲突?

当你只是改变一个文件的大小,它将是sparse ,这意味着没有数据的区域不占用磁盘空间。 空间在写入过程中分配 – 可以创建磁盘空间错误。

解决问题的一种方法是将(虚拟)数据写入文件,而不是仅仅改变大小。 这需要更多的时间,但是在第一个写入周期中,您只能获取磁盘空间,因为文件之后会有最终的大小。