在C ++中写入不可靠的磁盘时引发I / O错误

时间:2011-11-04 16:15:48

标签: c++ exception error-handling io writing

想象一下,你在C ++中有以下内容:

ofstream myfile;
myfile.open (argv[1]);

if (myfile.is_open()){
 for(int n=0;n<=10;n++){
     myfile << "index="<<n<<endl;
     sleep(1);
 }
}else{
cerr << "Unable to open file";
}

myfile.close();

在写入时,您正在写入的磁盘或介质变得不可用,但会在关闭()时返回,以便您之间缺少数据。或者想象一下你写入USB闪存驱动器,并且在写入过程中设备被撤回并重新插入。你怎么能发现这个?我试着检查把写入try {} catch,flags(),rdstate()你命名但是到目前为止似乎都没有。

4 个答案:

答案 0 :(得分:1)

我认为这不是你在stdio级别可以检测到的东西。通常,当硬盘驱动器暂时停止响应时,操作系统将自动重试命令,直到它们成功或达到超时,此时系统调用可能会收到错误。 (OTOH可能没有,因为在将数据写入内存文件系统缓存之后但在将任何命令发送到实际磁盘之前,您的调用可能已经返回了)

如果你真的想要检测flakey硬盘驱动器,你可能需要编写更低级别的代码,例如:编写自己的硬件驱动程序。

答案 1 :(得分:1)

恕我直言,您可以尝试:

  1. 使用ios:exceptions
  2. 使用低级别操作系统互动
  3. 验证IO是否成功(如果1和2不起作用)

答案 2 :(得分:0)

我不确定这是否会涵盖您的方案(在写入中删除USB驱动器),但您可以尝试在流上启用例外:

myfile.exceptions(ios::failbit | ios::badbit);

根据我的经验,iostream做了“很棒的”工作,难以发现错误和错误类型。

答案 3 :(得分:0)

for(int n=0;n<=10;n++){
    if (!(myfile << "index="<<n<<endl))
        throw std::runtime_error("WRITE FAILED")
    sleep(1);
}

如果std::ostream因任何原因失败,它会设置状态位,然后检查std::stream是否在布尔上下文中。这与检查std::istream数据是否正确读入变量的方式相同。

但是,这与您说过的rdstate()相同。如果是这种情况,则写入已经到达缓冲区。刷新程序缓冲区的endl表明它位于操作系统的缓冲区中。从那里,您将不得不使用特定于操作系统的调用来强制它刷新缓冲区。

[编辑]根据http://msdn.microsoft.com/en-us/library/17618685(v=VS.100).aspx,如果您有文件描述符,则可以强制使用_commit进行刷新。我找不到std::ostream的保证。