我正在尝试使用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
但如果我使用吃或什么都没有,它总是会删除文件的内容。
任何帮助都会很棒:)
答案 0 :(得分:5)
是的,导致此行为的是ios::app
。将其替换为ios::in | ios::out
。
编辑:您的问题并不清楚,但您的评论表明您尝试在文件中间插入数据,而不是< em>覆盖文件的一部分。如果确实如此,那么你几乎必须使用第二个文件。
答案 1 :(得分:1)
您是否尝试过使用ios::out
代替ios::app
?
编辑:
在阅读了@curiousguy引用的文档之后,看起来您需要ios::in | ios::out
而不仅仅是ios::out
才能避免截断。
答案 2 :(得分:1)
如果OS(和网络文件系统,如果适用)支持追加模式,则设置追加模式可确保在有多个写入器时,写入的数据不会覆盖文件中的现有数据。如果没有附加模式,这是你无法做到的事情,因为不同进程的搜索和写入之间的竞争。它是日志文件的重要保证。
在追加模式下,您只能按照定义在文件末尾写入。
根据[ofstream.cons],ofstream (s, mode)
致电rdbuf()->open(s, mode|ios_base::out)
。
根据[filebuf.members]中的“文件打开模式”表,filebuf::open
的行为是根据fopen
开放模式定义的:
out
表示“w”app
和app|out
表示“a”in|out
表示“r +”in|out|trunc
表示“w +”根据fopen man
,模式意味着:
最后,ate
表示fseek(file,0,SEEK_END)
。
因此,如果您想在不破坏现有数据的情况下打开任意位置进行书写,则需要fopen(s,"r+")
或ofstream (s, ios::in|ios::out)
。
IOW,在C / C ++中你还需要对文件进行读访问才能打开它而不会覆盖它!
您可能希望使用POSIX open
函数,以便直接访问POSIX开放标记:O_READ
,O_WRITE
,O_CREAT
,{{1} },O_EXCL
...与O_TRUNC
标志不同,它们不是更强大,但也是独立且表现良好的。
当然,此功能不是标准C ++的一部分。我相信所有相关的系统支持filebuf::open
。