【问题标题】:Truncating the file in c++在 C++ 中截断文件
【发布时间】:2011-08-15 06:29:54
【问题描述】:

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

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

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

到这里为止一切正常。但是,问题是我读取文件(最后 2MB)并清除文件(30MB 文件),然后写回最后 2MB。 如果在我从 1GB 文件复制最后 300MB 文件的情况下,将需要很多时间。

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

当日志文件较大时,应该并且将考虑以下原因。

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

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

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

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

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

【问题讨论】:

  • 附带说明,如果这是您的程序要做的所有事情,如果您在 *nix 系统上,则可以使用简单的 *nix 命令执行此操作。 dd 可以将所需的块复制到辅助文件中,然后从那里进行删除重命名...
  • @Thanatos 作为旁注,有几个 GNU 实用程序到 Windows 的端口。
  • 例如,tail --bytes=2MB file_name | xargs -0 echo > file_name

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


【解决方案1】:

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

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

为了提高复制的性能,您可以将数据复制到块中,您可以玩弄块大小以找到最佳值。

【讨论】:

  • 现在让我试一试!...担心从 1GB 文件中复制 300MB 文件.... :( 我将对其进行基准测试....
  • 临时文件在出现问题时有一定的鲁棒性,是个好主意,+1。例如,gparted 实际上会更改块大小,直到在复制/移动分区时找到合适的值。
  • 删除整个文件并回写所需的时间几乎。我可以尝试截断日志文件吗?不会做任何研究。
【解决方案2】:

如果这是您之前的文件:

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

- 是您不想要的,+ 是您想要的,这是最便携的获取方式:

++++

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

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

这样的操作很难实现,因为文件系统上的不同块大小(如果文件系统块大小)会导致麻烦。充其量,您将仅限于削减块大小的边界,但这将是哈利。这种情况很少见,这可能就是为什么不直接支持这种程序的原因。

【讨论】:

  • 同意!... 好吧,假设我反转文件并截断​​最后的 28MB... 你认为呢?你能给我一个截断文件的线索吗? (尾部本身)
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 2010-10-26
      • 2011-09-26
      • 1970-01-01
      • 2016-06-14
      • 2012-09-08
      • 2013-07-14
      • 2010-10-16
      • 1970-01-01
      • 2010-12-27
      相关资源
      最近更新 更多