在 ofstream 写入期间检测到空间不足,stream.fail() 无法工作
Posted
技术标签:
【中文标题】在 ofstream 写入期间检测到空间不足,stream.fail() 无法工作【英文标题】:Detecting insufficient space during ofstream write, stream.fail() failed to work 【发布时间】:2019-07-09 06:40:30 【问题描述】:我目前正在编写 DOD5220.22-M 的实现。下面的代码用于将二进制零写入文件,直到磁盘完全装满。
所以问题在于使用 statvfs,它检测到 3800158208 字节(约 3.82gb)的可写空间。但是,写入过程将在 3.77gb 处停止,并且将永远停留在那里。驱动器在此操作之前被格式化为 APFS,因此它是完全空的。
如您所见,我尝试使用 stream.fail() 来检测此类错误,但这似乎根本不起作用。系统是运行 g++8 和 C++17 的 MacOS
我错过了什么? statvfs 是否检测到比现有更多的可写空间,还是我做错了什么?
还有一种方法可以在每次迭代时不检查 stream.fail() 的情况下编写吗?
提前致谢。
statvfs("/Volumes/SECUREERASE", &space); // get space
size = space.f_frsize * space.f_bavail;
char zero = 0;
for (int i = 0; i < size; ++i) // while space left, write
file.write(&zero, sizeof(char));
if(file.fail())
break;
【问题讨论】:
IDK 出了什么问题,但为这种操作尝试较低级别的东西似乎是明智的。您是否尝试过 POSIX 函数,打开、写入、关闭等? 这是个好主意,约翰,我使用 fwrite() 测量了每 3gb 写入减少 2 秒。谢谢!不幸的是,问题仍然存在; 我不是指fwrite
(这是一个C函数)我指的是POSIX函数write
pubs.opengroup.org/onlinepubs/007904875/functions/write.html。只是一个建议,我不知道它是否有帮助。
感谢@john 的建议。它实际上解决了我的问题!我相信这是导致所有问题的缓冲区。使用 write 时,我将自己的缓冲区设置为 4mb 并写入磁盘大小/4mb 次,它工作完美。它也快得多。这是一个很棒的建议。再次感谢。
【参考方案1】:
在接受@john 的建议并使用 POSIX 写入并将我自己的缓冲区设置为 4MB 并写入磁盘大小/4MB 时间后,问题解决了。这是代码
int file = open("run1",O_WRONLY);
char zero[4000000] = 0;
for (long unsigned int i = 0; i < (size/4000000); ++i) // while space left, write
write(file,&zero, sizeof(zero)* sizeof(char));
虽然我仍然不确定究竟是什么导致了我的问题,但我可以确信它与 fstream 默认缓冲区大小有关。也许缓冲区大于剩余空间,因此无法写入文件,但这并不能解释为什么 stream.fail() 没有捕获它。问题还是解决了。
【讨论】:
现在我想起来了,写入失败会显示为file.bad()
而不是file.fail()
,这是因为转换错误等。
我都试过了,都失败了。我认为 fail() 只是一个 bad() + failbit。以上是关于在 ofstream 写入期间检测到空间不足,stream.fail() 无法工作的主要内容,如果未能解决你的问题,请参考以下文章