【问题标题】:fstream replace portion of a filefstream 替换文件的一部分
【发布时间】:2009-04-27 01:58:36
【问题描述】:

当我这样做时

fstream someFile("something.dat", ios::binary|ios::out);
someFile.seekp(someLocation, ios::beg);
someFile.write(someData, 100);

似乎用这 100 个字节替换整个文件,而不是只替换适当的 100 个字节,就好像我指定了 ios::trunc。有没有一种不截断文件的便携方法?

编辑: 添加 ios::in 似乎可以解决问题,为什么这是必需的,这是标准行为吗?

编辑#2:我不想追加到现有文件。我需要替换 100 个字节,而其余部分不受影响。

【问题讨论】:

    标签: c++ io fstream


    【解决方案1】:

    如果要在文件末尾写入,则需要附加标志 ios::app。

    要在文件中间任意位置执行此操作,您需要找到正确的位置。您可以通过打开文件输入和输出来执行此操作,但如果我是您,我会创建一个临时文件,将输入复制到标记,写入新数据,将其余数据复制到 EOF,关闭文件并替换以前的文件带有临时文件的版本。这称为“主文件更新”。

    【讨论】:

    • 输入和输出是非标准的,还是您只建议使用这种替代方法来保证数据安全?
    • 进出是标准的,只是很难让代码正确。使用面向记录或固定格式的数据更容易一些,但在类 C 语言中执行 IO 的默认方式是可变长度的基于文本的记录,或纯二进制。因此,如果您的大小或偏移量错误,或者您有多个编写器,您可以修改整个文件。如果您进行主文件更新,您至少应该得到一个内部一致的文件。
    【解决方案2】:

    AFAIR ios::out 仅指定文件用于输出,而 ios:binary 仅指定文件为二进制文件。流的默认行为是创建一个新文件并覆盖旧文件。如果要修改现有文件,必须使用 ios::app 标志打开文件。

    ATM 我无法检查我的参考资料,因此请务必仔细检查,但我认为这是准确的。

    【讨论】:

      【解决方案3】:

      由于文件已经存在,以“读+写”模式打开它,然后执行 seekp。我认为它会起作用。

      fstream someFile("something.dat", ios::binary|ios::out|ios::in);
      someFile.seekp(someLocation, ios::beg);
      someFile.write(someData, 100);
      

      【讨论】:

        【解决方案4】:

        ios:in 掩码告诉文件指针指向文件开头的位置,以便它可以从头开始读入。但是,您可能希望使用 fseek 将文件指针设置在文件的开头。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-10
          • 2020-08-01
          • 2013-12-01
          • 1970-01-01
          相关资源
          最近更新 更多