我正在用c++写一个程序,想知道是否有人可以帮助我解决这里解释的情况。
-
假设,我有一个大约30MB大小的日志文件,我已经将最后2MB的文件复制到程序中的缓冲区。
-
我删除文件(或清除内容),然后写回我的2MB文件
在此之前一切都很好。但是,问题是我读取文件(最后2MB)并清除文件(30MB文件),然后回写最后2MB。如果在从1GB文件复制最后300MB文件的场景中,将需要太多的时间。
有没有人有让这个过程更简单的想法?
当有一个大的日志文件时,应该并且将考虑以下原因:
磁盘空间:日志文件是未压缩的纯文本,占用大量空间。典型压缩将文件大小减少10:1。但是,文件不能被压缩当它正在使用时(锁定)。因此,必须将日志文件旋转出来。
系统资源:定期打开和关闭文件会消耗大量的系统资源资源,它会降低服务器的性能。
文件大小:小文件在故障时更容易备份和恢复。
我只是不想复制,清除和重写最后的特定行到一个文件。只是一个更简单的过程....: -)
编辑:不做任何内部进程来支持日志旋转。logrotate是工具。
我建议你用一种稍微不同的方法。
- 创建新的临时文件
- 将所需数据从原始文件复制到临时文件
- 关闭文件
- 删除原文件
- 将临时文件重命名为与原始文件相同的名称
为了提高复制的性能,您可以将数据以块的形式复制,您可以使用块大小来找到最优值。
如果这是你之前的文件:
-----------------++++
其中-
是你不想要的,+
是你想要的,最便携的方法:
++++
…正如你所说的。读取您想要的部分(+
),删除/清除文件(与fopen(... 'wb') or something similar
一样)并写出您想要的位(+
)。
任何更复杂的东西都需要特定于操作系统的帮助,并且是不可移植的。不幸的是,我不相信任何主流的操作系统都支持你想要的。可能会支持"截断位置X之后的"(一种head
),但不支持您请求的tail
类操作。
这样的操作很难实现,因为在文件系统上改变块大小(如果文件系统有块大小)会造成麻烦。在最好的情况下,你将被限制在块大小的边界上切割,但这将是哈里。这是一种非常罕见的情况,这可能就是为什么不直接支持这种过程的原因。
更好的方法可能是不让文件变得那么大,而是使用轮换日志文件,每个日志文件设置最大大小,并保留最大数量的旧文件。
如果您可以控制写入过程,那么您可能想要在这里做的是像循环缓冲区一样写入文件。这样你就可以保留最后X字节的数据,而不必做你所建议的。
即使你不能控制写入过程,如果你至少可以控制它写入哪个文件,那么也许你可以让它写入一个命名管道。您可以在此命名管道的末尾附加自己的程序,该程序将写入循环缓冲区,如前所述。