重新打开已关闭的文件流

时间:2016-10-10 17:58:57

标签: c++ c++11 visual-c++ c++14

考虑以下代码,

auto fin = ifstream("address", ios::binary);
if(fin.is_open()) 
    fin.close()
for(auto i = 0; i < N; ++i){
    fin.open()
    // ....
    // read (next) b bytes...
    // ....
    fin.close()
    // Some delay
}

上面的代码无法在我知道的C ++中实现,但我想知道是否可以这样做?

以下是我的要求:

  • 重新打开文件时,无需再次传递参数(路径和模式)。
  • 重新打开流时,它会从关闭时的流中的点继续。

澄清

  • 我使用的文件很大,并且在某个时间点,来自第三方库的其他线程可能决定(重新)移动它们。开放流将阻止此类行为。
  • 连续读取大文件会降低系统速度。

1 个答案:

答案 0 :(得分:1)

需要

实际上,只要流保持文件打开,文件就不能被另一个进程删除。

我想你已经问过自己这些问题了,但是对于这些问题我不得不建议你去考虑一下:

  • 文件是否可以读入(虚拟)内存并在不再需要时丢弃?
  • 文件处理是否可以异步流水线化,立即读取并处理它而不会造成不必要的延迟?
  • 如果文件因其被其他进程删除而无法再打开,该怎么办?如果无法找到位置该怎么办,因为文件已被修改(例如缩短)?
  • 如果您对问题有完美的解决方案,如果其他进程在打开时尝试删除该文件会有什么影响(只是很短的时间,但仍然打开并阻止删除)?

解决方案

不幸的是,您无法通过标准流实现所需的行为。您可以通过跟踪文件名和位置(以及更常见的状态)来模拟它:

   auto mypos = ifs.tellg();  // saves position.  
                              // Should flag be saved as well ? and what about gcount ?
   ifs.close();  

   ...

   if (! ifs.is_open()) {
       ifs.open(myfilename, myflags);  // open again !  
       if (! ifs) { 
           // ouch ! file disapeared ==> process error 
       }
       ifs.seekg(mypos);              // restore position 
       if (! ifs) { 
           // ouch ! position no longer reachable  ==> process error 
       }
   }

当然,你永远不想重复这段代码。突然有很多全局变量来跟踪流的状态并不是那么好。但是你可以很容易地将它封装在一个包装类中,该类将使用现有的标准操作来保存和恢复流的状态。