1

想象一下,您在 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();

在写入时,您正在写入的磁盘或介质变得不可用,但会在 close() 时重新打开,因此您之间会丢失数据。或者想象您写入 USB 闪存驱动器,并且在写入过程中设备被取出并重新插入。你怎么能检测到呢?我尝试检查将写入放入 try {} catch、flags()、rdstate() 中,但到目前为止似乎没有任何效果。

4

4 回答 4

1

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

如果你真的想检测易碎的硬盘驱动器,你可能需要编写低得多的代码,例如编写你自己的硬件驱动程序。

于 2011-11-04T16:19:52.570 回答
1

恕我直言,您可以尝试:

  1. 使用ios:异常
  2. 使用低级操作系统交互
  3. 验证 IO 是否成功(如果 1 和 2 不起作用)
于 2011-11-04T16:26:10.333 回答
0

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

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

以我的经验,iostreams 在使检测错误和错误类型变得困难方面做得“很棒”。

于 2011-11-04T16:25:23.313 回答
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::ostreams 找到这样的保证。

于 2011-11-04T16:27:10.970 回答