用c++截断文件

Truncating the file in c++

本文关键字:文件 c++      更新时间:2023-10-16

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

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

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

在此之前一切都很好。但是,问题是我读取文件(最后2MB)并清除文件(30MB文件),然后回写最后2MB。如果在从1GB文件复制最后300MB文件的场景中,将需要太多的时间。

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

当有一个大的日志文件时,应该并且将考虑以下原因:

磁盘空间:日志文件是未压缩的纯文本,占用大量空间。典型压缩将文件大小减少10:1。但是,文件不能被压缩当它正在使用时(锁定)。因此,必须将日志文件旋转出来。

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

文件大小:小文件在故障时更容易备份和恢复。

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

编辑:不做任何内部进程来支持日志旋转。logrotate是工具。

我建议你用一种稍微不同的方法。

  1. 创建新的临时文件
  2. 将所需数据从原始文件复制到临时文件
  3. 关闭文件
  4. 删除原文件
  5. 将临时文件重命名为与原始文件相同的名称

为了提高复制的性能,您可以将数据以块的形式复制,您可以使用块大小来找到最优值。

如果这是你之前的文件:

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

其中-是你不想要的,+是你想要的,最便携的方法:

++++

…正如你所说的。读取您想要的部分(+),删除/清除文件(与fopen(... 'wb') or something similar一样)并写出您想要的位(+)。

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

这样的操作很难实现,因为在文件系统上改变块大小(如果文件系统块大小)会造成麻烦。在最好的情况下,你将被限制在块大小的边界上切割,但这将是哈里。这是一种非常罕见的情况,这可能就是为什么不直接支持这种过程的原因。

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

如果您可以控制写入过程,那么您可能想要在这里做的是像循环缓冲区一样写入文件。这样你就可以保留最后X字节的数据,而不必做你所建议的。

即使你不能控制写入过程,如果你至少可以控制它写入哪个文件,那么也许你可以让它写入一个命名管道。您可以在此命名管道的末尾附加自己的程序,该程序将写入循环缓冲区,如前所述。