4

我正在尝试使用 C++ 在文件的特定位置写入条目

所以基本上我有

ofstream ofs("file.dat", ios::binary | ios::app);
ofs.seekp(220, ios::beg);
ofs.write((char *)&i, sizeof(i));

但无论我做什么,它总是写在文件的末尾。

我想这与iso::app因为根据文档

app (append) Set the stream's position indicator to the end of the stream before each output operation

但是如果我使用ate或 nothing 它总是会删除文件的内容。

任何帮助都会很棒:)

4

3 回答 3

5

是的,这ios::app是导致这种行为的原因。将其替换为ios::in | ios::out

编辑:您的问题并不清楚,但您的评论表明您正在尝试在文件中间插入数据,而不是覆盖文件的一部分。如果确实如此,那么您几乎必须为此使用第二个文件。

于 2011-10-28T11:38:44.800 回答
3

文件附加模式

如果操作系统(和网络文件系统,如果适用)支持追加模式,则设置追加模式可确保写入的数据不会在有多个写入者时覆盖文件中的现有数据。这是你不能没有附加模式的事情,因为来自不同进程的查找和写入之间的竞争。是日志文件的重要保障。

在追加模式下,您只能根据定义在文件末尾写入。

iostream 开放模式

根据 [ofstream.cons],ofstream (s, mode)调用rdbuf()->open(s, mode|ios_base::out).

根据 [filebuf.members] 中的“文件打开模式”表,根据打开模式filebuf::open定义的行为fopen

  • out意思是“w”
  • app意思app|out是“一个”
  • in|out意思是“r+”
  • in|out|trunc意思是“w+”

根据fopen man,模式意味着:

  • r+ 打开用于读写。
  • w 将文件截断为零长度或创建文本文件以进行写入。
  • w+ 开放阅读和写作。如果文件不存在,则创建该文件,否则将其截断。
  • a 打开以追加(在文件末尾写入)。如果文件不存在,则创建该文件。

最后,ate意味着fseek(file,0,SEEK_END)

所以,如果你想在任意位置打开写入,而不破坏现有数据,你需要fopen(s,"r+")or ofstream (s, ios::in|ios::out)

IOW,在 C/C++ 中,您还需要对文件进行读取访问才能打开它进行写入而不覆盖它!

POSIX 世界

您可能希望使用 POSIXopen函数来直接访问 POSIX 开放标志:O_READ, O_WRITE, O_CREAT, O_EXCL, O_TRUNC... 与标志不同,它们不仅更强大,而且独立的正交标志和行为良好filebuf::open

当然,这个函数不是标准 C++ 的一部分。我相信所有与正常编程相关的系统(不是具有特殊特征的利基市场)都支持open

于 2011-10-28T13:33:30.813 回答
1

您是否尝试过使用ios::out而不是ios::app

编辑:

在阅读了@curiousguy 引用的文档之后,看起来您需要ios::in | ios::out而不是仅仅ios::out为了避免截断。

于 2011-10-28T11:39:26.217 回答