用c ++截断文件

时间:2011-04-29 06:06:52

标签: c++ file file-io logging filestream

我正在用C ++编写一个程序,并想知道是否有人可以帮助我解释这里解释的情况。

  1. 假设我有一个大约30MB的日志文件,我已将最后2MB的文件复制到程序中的缓冲区。

  2. 我删除文件(或清除内容),然后将2MB写回文件。

  3. 直到这里一切正常。但是,关注的是我读取文件(最后2MB)并清除文件(30MB文件)然后写回最后2MB。 如果在我从1GB文件复制最后300MB文件的情况下,将需要大部分时间。

    有没有人想过让这个过程更简单?

    当拥有大型日志文件时,应考虑以下原因。

    磁盘空间:日志文件是未压缩的纯文本,占用大量空间。 典型压缩会将文件大小减小10:1。但是无法压缩文件 当它在使用(锁定)。因此必须将日志文件轮换使用。

    系统资源:定期打开和关闭文件会占用大量系统 资源,它会降低服务器的性能。

    文件大小:小文件在发生故障时更容易备份和还原。

    我只是不想复制,清除并重写最后一行到文件。只是一个更简单的过程....: - )

    编辑:没有任何内部进程来支持日志轮换。 logrotate是工具。

4 个答案:

答案 0 :(得分:5)

我建议采用略有不同的方法。

  1. 创建新的临时文件
  2. 将所需数据从原始文件复制到临时文件
  3. 关闭两个文件
  4. 删除原始文件
  5. 将临时文件重命名为与原始文件相同的名称
  6. 为了提高副本的性能,您可以以块的形式复制数据,您可以使用块大小来查找最佳值。

答案 1 :(得分:1)

如果这是您之前的文件:

-----------------++++

-是您不想要的地方,+就是您想要的,最便携的方式:

++++

......就像你说的那样。阅读您想要的部分(+),删除/清除文件(与fopen(... 'wb') or something similar一样,并写出您想要的位(+)。

任何更复杂的事情都需要特定于操作系统的帮助,并且不可移植。不幸的是,我不相信任何主要的操作系统都支持你想要的东西。可能支持“在位置X之后截断”(一种head),但不支持您要求的tail类似操作。

这样的操作很难实现,因为文件系统上的变化块(如果文件系统具有块大小)会导致麻烦。充其量,你只能限制在块大小的边界上,但这会很难。这是一种罕见的情况,这可能就是为什么不直接支持这样的原因。

答案 2 :(得分:1)

更好的方法可能不是让文件变得那么大,而是使用每个日志文件设置最大大小的旋转日志文件以及保留的最大旧文件数。

答案 3 :(得分:0)

如果你可以控制写作过程,你可能想要做的就是像circular buffer一样写入文件。这样你就可以保留最后X个字节的数据而不必按照你的建议进行操作。

即使您无法控制写入过程,如果您至少可以控制它写入的文件,那么也许您可以将其写入named pipe。您可以在此命名管道的末尾附加您自己的程序,该管道将按所讨论的方式写入circular buffer