【问题标题】:inheriting from std::ostream (to avoid rewriting same old content)...?从 std::ostream 继承(以避免重写相同的旧内容)...?
【发布时间】:2015-09-27 15:37:37
【问题描述】:

我想要一些 C++11 输出流,只有当新写入的内容与前一个不同时才会写入文件(如果内容与磁盘上现有的内容相同,我不想要更改原始文件的元数据)。

FWIW,该程序在 GNU/Linux/Debian/Sid x86-64 上,由最近的 GCC 5(或更高版本)编译。它是一个类似服务器的程序,最多只有一个进程在运行它。系统上不应有其他进程写入该文件。

我想避免覆盖现有的相同文件内容的原因是因为实际输出是一些*.h C++ 头文件....(如果这很重要,它是未来MELT 监视器的新化身,我正在用 C++11 重新设计和重写this),如果生成的头文件没有改变,我不希望未来的make 构建根据它重新编译东西。

我很想继承std::ofstream(那么,初始文件路径将是一些临时路径名)或std::ostringstream(然后,整个文件内容都保存在内存中,对我来说没什么大不了的),并重新定义其close 方法以将新内容与磁盘上的旧内容进行比较,并且仅当该内容发生更改时才重写磁盘文件。

但我觉得它闻起来不好(甚至是错误的),特别是因为 std::ofstream::close 没有记录为 virtual。我应该改用std::filebuf 吗?

我有很多现有的operator <<,左边的操作数是std::ostream&,右边是我自己的一些类,我想在我的特殊流中使用它们。 我已经有很多函数可以输出到任何std::ostream,我想在这样的“差异”文件流上使用其中的一些......

或者我应该从std::ostream继承(因此我稍微改变了最初提到std::ofstream,而不是std::ostream的问题的标题)?

我会在关闭的时候比较新旧内容(只需关闭临时文件,并读取它和旧文件,然后逐字节比较)。

【问题讨论】:

  • 听起来这不是文件流的工作。流是数据流(在这种情况下,用于文件存储),但它不是文件。
  • 为什么?那有什么不同,例如来自popen 的 C 语言?
  • 你有什么建议?我有很多使用std::ostream 的功能,我希望它们能够输出到这样的东西。

标签: c++ linux c++11 gcc


【解决方案1】:

不要。流是数据流,而不是文件。让这个功能在流附近的任何地方都是不合适的。如果不出意外,尽管您可能会破解一种方法来尽早确定源和目标是否相同,但这会破坏流的 FIFO 模型。它们只是不适合这项工作。

将您的文件生成到一个临时位置,然后执行md5sum 比较并将其(通过覆盖)移动到目标路径如果内容不同;否则只需删除临时文件。当然它不需要比这更复杂。

【讨论】:

  • 重点是我希望这些东西尽可能透明地用作std::ostream
  • @BasileStarynkevitch:嗯,正如解释的那样,我只是认为这是一个糟糕的主意。作为使用您的代码的程序员,这将是非常令人惊讶的,而且不仅仅是有点混乱。我根本不清楚语义和行为以及潜在的边缘情况。您正在尝试将流视为流以外的东西。最终,我无法阻止你。 :)
  • 您在考虑哪些极端情况?
  • @BasileStarynkevitch:我不能告诉你它们是什么,因为它们是出乎意料的。如果不了解更多关于如何确定两个文件是否相同、新数据可用的块大小以及代码结构的更多信息,就不可能回答这个问题。这个问题太模糊了。
【解决方案2】:

我的心智模型是 streambuf 是内部实现者的接口,而 stream 只是使其使用方便的包装器。因此,要更改功能,您通常会在 streambuf 级别定义事物,其中有很多虚函数需要覆盖。但我远不是这方面的专家。

您也许可以小心地将修改后的filebuf 与原版ofstream 一起使用。

【讨论】:

    【解决方案3】:

    虽然编写一个新的 streambuf 可能是要走的路,但一种方法是你的新类 is-a ostream 内部 has-a fstream。也就是说,它继承自抽象基类,并有一个代表底层文件的私有数据成员。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-13
      • 1970-01-01
      • 2021-04-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多