如何通过fstream.close()和后续的.open()来影响iostate位?

时间:2014-11-12 12:43:46

标签: c++

我有一个ofstream对象,我定期重新打开,并使用新的文件名。我知道.clear()会将iostate重置为goodbit。但是,如果此状态受.close.open影响,我并不完全清楚。

特别是,我可以在.fail()之后检查.close()以确定我是否应该::remove该文件?我不想保留损坏或部分文件。

如果badbit和/或failbit不受.close影响,我应该在致电.clear之前明确.open(newPath)吗?我已经发现这些位被.open清除,正式来自C ++ 11,但非正式地大多数实现都是这样做的。

1 个答案:

答案 0 :(得分:4)

来自[ifstream.members] / 5:

  

void close();

     

效果:调用rdbuf()->close()如果该函数返回空指针,则调用setstate(failbit) (可能会抛出ios_base::failure(27.5.5.4))。

总结[filebuf.members] / 6:

  

basic_filebuf<charT,traits>* close();

     
      
  • 如果is_open() == false,则返回空指针。
  •   
  • 如果函数[...]发出的任何调用失败,则close会因返回空指针而失败。
  •   
  • 如果存在展示区域,请拨打 overflow(traits::eof()) 以刷新字符。
  •   
  • 如果在*thisunderflowoverflowseekoffseekpos之间)调用的最后一个虚拟成员函数是overflow,那么致电 a_codecvt.unshift
  •   
  • 最后[...]函数关闭文件(就好像通过调用std::fclose(file)
  •   

overflow([filebuf.members] / 10)在以下时间失败:

    如果codecvt::out“遇到无法转换的字符,则
  • codecvt失败”([locale.codecvt.virtuals] / 5)。
  • 文件输出失败(未指定,可能是fwrite在大多数实现中失败)。
如果“发生了未指定的错误”,则

codecvt::unshift失败“([locale.codecvt.virtuals] / 8)。

如果检测到任何错误,

std::fclose将失败。 (C11 7.21.5.1)。

  

特别是,我可以在.close()之后检查.fail()以确定我是否应该::删除文件?

正如我们所看到的,close如果文件本身存在问题,或者如果codecvt遇到无法转换的字符(或者unshift失败的极少数情况下),则可能会失败。如果您因文件问题需要绝对确定close失败,则需要在关闭之前执行os.seekp(0, os.end).clear();之类的操作,以确保close唯一能做的就是调用{ {1}}。