C ++ fstream从选定的点中删除文件内容

时间:2010-10-24 09:44:54

标签: c++ visual-c++ file-io

我需要从选定的点(C ++ fstream)中删除文件内容我应该使用哪个函数?

我写了objects,我需要在文件中间删除这些objects

2 个答案:

答案 0 :(得分:7)

C ++没有标准机制来截断给定点的文件。您必须重新创建文件(使用ios::trunc打开并编写要保留的内容)或使用特定于操作系统的API调用(SetEndOfFile在Windows上,truncate或{{1}在Unix上)。

编辑:删除文件中间的内容非常不稳定。在考虑任何其他替代方案之前,我会尝试使用像SQLite这样的无服务器数据库引擎来存储序列化对象。更好的是,我会按照预期使用SQLite,将这些对象所需的数据存储在适当的模式中。

编辑2:如果问题陈述需要原始文件访问权限......

作为一般规则,您不会从文件中间删除数据。如果可以将对象序列化为磁盘上的固定大小,则可以将它们作为记录使用,而不是尝试删除数据,而是使用索引文件中的记录的表。例如,如果按顺序写入四条记录,该表将保留ftruncate。要删除第二条记录,只需从表中删除其条目:[0, 1, 2, 3]。至少有两种方法可以重复使用表格留下的漏洞:

  1. 在每次插入时,扫描第一个未使用的索引,并在相应的记录位置写出对象。但是,随着文件的增长,这将变得更加昂贵。
  2. 维护免费列表。将最近释放的记录的索引存储为单独的变量。在该记录占用的空间中编码在其之前释放的记录的索引,依此类推。这保留了一个方便的免费记录链表,同时只需要一个额外数字的空间。但是,使用它会更复杂,并且在删除和插入时需要额外的磁盘I / O.
  3. 如果对象无法序列化为固定长度,则这种方法变得更加困难。可变长度记录管理代码非常复杂。

    最后,如果问题陈述要求在磁盘上按顺序保存记录,那么这是一个愚蠢的问题陈述,因为在文件中间的插入/删除是非常昂贵的;没有理智的设计需要这个。

答案 1 :(得分:2)

一般方法是打开文件进行读访问,打开新文件进行写访问,读取第一个文件的内容,并将要保留的数据写入第二个文件。完成后,删除第一个文件,并将第二个文件重命名为第一个文件。