【问题标题】:Proper choice of file stream objects正确选择文件流对象
【发布时间】:2026-01-03 05:25:02
【问题描述】:

应用程序使用 RapidXML 来编辑 XML 文件。编辑不是自动化的,偶尔会发生:XML 内容显示在 GUI 中,用户执行一些更改 XML 的操作。每个更改都必须立即保存到磁盘。

加载 RapidXML 文档对象需要将文件内容复制到字符串中。文档中的每次更改都会将文档对象的内容复制回文件中。

在此示例中,文件用于输入和输出。 在这种情况下,是否应将单个 std::fstream 对象用于所有输入/输出操作?它将在应用程序启动时打开一次,用于输入/输出,并在应用程序结束时关闭。

或者,当需要执行文件输入/输出时,是否应该使用 std::ifstreamstd::ofstream 的本地(临时)实例?例如。 std::ifstream 用于开始读取文件(打开、读取、关闭);同样,std::ofstream 实例在必须将 DOM 导出到文件(打开、写入、关闭)时使用。

我不关心这里的性能(由于应用程序的性质),但对在这种情况下正确选择文件流对象感到好奇。

【问题讨论】:

    标签: c++ fstream ifstream ofstream rapidxml


    【解决方案1】:

    当要重写的数据量与原始数据不同时,在适当的位置编辑文件是一件非常痛苦的事情。如果你的文件格式要求数据是连续的并且没有空洞的语法,那么你别无选择,只能重写文件(至少从修改位置的开头) .

    此外,还有其他限制。如果您需要在继续之前将数据刷新到磁盘,那么您可以使用单个std::fstream 进行多次编辑。即使您在文件流上调用flush() 方法,操作系统通常也不会将文件刷新到磁盘。一些平台提供非便携式解决方案来真正强制写入。因此,如果您需要将其刷新到磁盘,最好的办法是实际关闭该文件。

    因此,特别是对于关键应用程序,我会推荐第二种方法(ifstream 在初始加载时,ofstream 在每次写入时)。我还建议写入一个临时文件,然后将完整的重写移动到首选位置,替换原始文件。这可确保您不会丢失任何数据(至少在提供原子文件移动的系统上)。

    【讨论】:

      【解决方案2】:

      我绝对喜欢 std::ifstream 的本地临时实例和 std::ofstream。我什至不确定它是否会起作用;打开一个 std::ofstream 清空现有文件的内容。只求 到开头并且覆盖不会删除任何以前的内容, 如果更改的结果缩短了文件,你仍然会被留下 带有早期内容中的剩余字符。

      【讨论】: