c++ - 重新打开一个关闭的文件流

标签 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++实现,但我想知道是否可以这样做?

这是我的要求:

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

澄清

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

最佳答案

需求

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

我想你已经问过自己这些问题了,但是为了记录我必须建议你考虑一下:

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

解决方案

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

   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 
       }
   }

当然,您不希望永远重复此代码。突然间有很多全局变量来跟踪流的状态,这可不是什么好事。但是您可以非常轻松地将它封装在一个包装器类中,该包装器类将使用现有的标准操作负责保存和恢复流的状态。

关于c++ - 重新打开一个关闭的文件流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39964099/

相关文章:

visual-c++ - CMenu 和基于对话框的应用程序

c++ - 从模板包生成所有大小为 N 的子包

java - 执行在 "Microsoft Visual C++ Runtime Error"-popup 时停止

c++ - 如何在虚幻引擎项目中使用C++ Core Checker?

c++ - 使用 Direct2D 绘制 SVG 路径 : Can't draw elliptical arc

c++11 - 可变长度数组也是 Clang 中的扩展吗?

c++ - 使用类似策略模式的文件解析器 - 如何获得结果?

python - 通过 pip : Microsoft Visual C++ 14. 安装 lxml 时出错 0 是必需的

c++ - 字符串操作——需要更好的方法

C++ - 通过初始化列表构造 unique_ptr 的 vector