【问题标题】:Is file ready to read immediately after std::ofstream is destroyed?文件是否准备好在 std::ofstream 被销毁后立即读取?
【发布时间】:2013-06-21 15:09:50
【问题描述】:

基本上我有以下工作流程(通过控制台应用程序):

  • 读取二进制文件(std::ifstream::read
  • 读取数据做一些事情
  • 回写到同一个文件 (std::ofstream::write),覆盖什么 以前在那里。

现在,如果我通过 shell 脚本运行整个控制台程序 1000 次(总是使用同一个文件),是否可以安全地假设读取操作不会与之前运行的尝试写入文件的程序冲突?或者我需要在两次执行之间等待(多长时间???)?我能否可靠地确定文件是否准备就绪?

我知道这不是最好的设计,只是想知道它是否可以可靠地工作(尝试快速收集一些统计信息 - 输入不同,但输出文件始终相同 - 需要读取,需要处理信息,那么它需要更新(此时只需覆盖它)。

编辑:

看起来输出错误的问题与基于答案的操作系统无关,我所做的读/写看起来像:

//read
    std::ifstream input(fname,std::ios_base::binary);
    while(input)
    {
        unsigned value;
        input.read(reinterpret_cast<char*>(&value),sizeof(unsigned));
        ....
    }
    input.close();
...

//write
    std::ofstream output(fname,std::ios_base::binary);
    for(std::map<unsigned,unsigned>::const_iterator iter =originalMap.begin();iter != originalMap.end();++iter)
    {
        unsigned temp = iter->first;
        output.write(reinterpret_cast<char*>(&temp),sizeof(unsigned));
        temp = iter->second;
        output.write(reinterpret_cast<char*>(&temp),sizeof(unsigned));
    }

【问题讨论】:

  • 程序实例是同时运行还是顺序运行?
  • @Matteo Italia - 它们按顺序运行,本质上,shell 脚本循环运行相同的控制台应用程序...

标签: c++ std fstream ifstream ofstream


【解决方案1】:

它们按顺序运行,本质上,shell 脚本循环运行相同的控制台应用程序...

那么,在任何“正常”的操作系统上,应该都没有问题。

当应用程序终止时,流被销毁,因此 C/C++ 流可能保存在缓存中的所有数据都写入底层 OS 流,然后关闭。

操作系统是否进行更多缓存无关紧要 - 操作系统完成的缓存对应用程序是透明的,因此,就应用程序而言,数据现在写入文件中。如果它实际上是写在磁盘上的,这无关紧要——从文件中读取的应用程序无论如何都会看到其中的数据。

如果您考虑一下,如果没有这样的保证,在计算机上可靠地完成任何工作都会很复杂! :)


更新:

std::ofstream output(fname,std::ios_base::binary);

你应该在写入之前截断输出文件,否则,如果输入文件比输出文件长,旧数据仍然会留在文件末尾:

std::ofstream output(fname,std::ios_base::binary | std::ios_base::trunc);

【讨论】:

  • 问题是,我没有得到正确的输出 - 最后文件有一些无意义的数据..
  • @IlyaKobelevskiy:那么您的代码中可能还有其他问题。你在写之前截断文件吗?如果不是(=你只是在开头做一个seek,然后是一个write),那么最后的数据可能是输入文件的残留物。
【解决方案2】:

检查fstream ctor 的参数。一些实现有扩展,允许方便地设置共享模式。

如果您要求独占读取或写入,只要您保持流打开,就会得到这样的结果——其他类似的操作不会发生在不同的进程中,也不会发生在不同的流实例中。

对于纯标准,它需要更多的啤酒花,可能将它们设置在 filebuf 中并替换库存的啤酒花。照顾它。

使用共享模式是维护文件一致性的主流方式,所以我建议无论如何都要使用它。

当然,如果您确保处理了竞争条件,一个进程不会在另一个进程关闭文件之前打开文件,结果也很好。

【讨论】:

  • 问题是我从不同的进程中读取它(在之前写入它的控制台应用程序退出之后)......所以,我知道写入流被破坏了,但是,这是否意味着之后我可以立即从磁盘读取吗?
  • 在阅读器部分使用 read+deny_write ,如果您可以打开文件内容肯定是最终的。在作家最好用 write+deny_all 创造新鲜的邪恶。在让阅读器只打开现有文件,那么一切都是花花公子。
  • @MatteoItalia:你似乎是对的,我正在阅读gamedev.net/topic/93785-sharing-file-w-fstream,那么肯定有更长的路要走,摆弄filebuf。
  • @BalogPal:可能只是一个非标准的扩展。
猜你喜欢
  • 2022-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多