|
|
1
6
我认为你最好简单地:
通过简单地将最后512K复制到缓冲区,以截断模式打开日志文件(清除日志文件的内容),并将相同的512K吐回文件开头,可以避免文件重命名。 请注意,上述代码尚未经过测试,但我认为这个想法应该是合理的。 您可以将512K加载到内存中的缓冲区中,关闭输入流,然后打开输出流;这样,您就不需要两个文件,因为您可以输入、关闭、打开、输出512个字节,然后执行。这样可以避免重命名/文件重定位的魔法。 如果你在某种程度上不讨厌将C与C++混合使用,你也可以: (注意:伪代码;我记不起我脑子里的mmap调用了)
取决于很多事情,mmap 可以是 比寻找更快。如果你好奇的话,在谷歌上搜索“fseek vs mmap”会得到一些有趣的阅读材料。 人酪氨酸羟化酶 |
|
|
2
3
我可能会:
要执行前三个步骤(省略错误检查,例如,如果文件小于500k大,我不记得seekg会做什么):
然后我认为你必须做一些非标准的事情来重命名文件。 不过,显然你需要500k的可用磁盘空间才能工作,所以如果你截断日志文件的原因是因为它刚刚填满了磁盘,这是不好的。 我不知道为什么搜索速度很慢,所以我可能错过了什么。我不认为查找时间取决于文件的大小。可能取决于文件的是,我不确定这些函数是否在32位系统上处理2GB以上的文件。 如果复制本身很慢,那么根据平台的不同,您可以通过使用更大的缓冲区来加速它,因为这减少了系统调用的次数,更重要的是,磁盘头必须在读取点和写入点之间进行搜索的次数。为此,请执行以下操作:
用不同的值进行测试,然后查看。你也可以尝试增加ofstream的缓冲区,我不确定这是否会有所不同。 请注意,在“实时”日志文件上使用我的方法很麻烦。例如,如果在副本和重命名之间附加了一个日志条目,那么你将永远丢失它,并且你试图替换的文件上的任何打开的句柄都可能导致问题(在Windows上它会失败,在linux上它会替换文件,但旧的仍将占用空间,并且在句柄关闭之前仍会被写入)。 如果截断是从执行所有日志记录的同一线程完成的,那么就没有问题,你可以保持简单。否则,您将需要使用锁或其他方法。 这是否完全稳健取决于平台和文件系统:移动和替换可能是也可能不是原子操作,但通常不是,因此您可能必须先重命名旧文件,然后重命名新文件,然后删除旧文件,并进行错误恢复,启动时检测是否有重命名的旧文件,如果有,将其放回并重新启动截断。STL不能帮助您处理平台差异,但有boost::filesystem。 很抱歉,这里有很多警告,但很大程度上取决于平台。如果你在PC上,那么我很困惑为什么复制区区半兆的数据需要任何时间。 |
|
|
3
3
如果你碰巧使用窗户,不要费心四处复制零件。只需通过调用以下命令告诉Windows您不再需要第一个字节
|
|
|
4
1
如果您可以在重新初始化之间生成几GB的日志文件,那么仅在初始化时截断该文件似乎并没有什么帮助。 我想我会尝试提出一种专门的文本文件格式,以便始终替换原地的内容,并用指向“当前”行的指针环绕。您需要一个恒定的线宽来分配一次磁盘空间,并将指针放在该文件的第一行或最后一行。 这样,文件就永远不会增长或收缩,你总是会得到最后一个 N 条目。 插图 N =6(“|”表示空格填充到那里): #myapp logfile, lines = 6, width = 80, pointer = 4 | [2008-12-01 15:23] foo bakes a cake | [2008-12-01 16:15] foo has completed baking a cake | [2008-12-01 16:16] foo eats the cake | [2008-12-01 16:17] foo tells bar: I have made you a cake, but I have eaten it | [2008-12-01 13:53] bar would like some cake | [2008-12-01 14:42] bar tells foo: sudo bake me a cake | |
|
|
5
1
另一种解决方案是让日志类检测日志文件大小何时超过500k,并打开一个新的日志文件,然后关闭旧的日志文件。 然后,日志类将查看旧文件,并删除最旧的文件 记录器将有两个配置参数。
这样,日志文件管理将是一个自我维护的东西。 |
|
|
6
0
所以你想要文件的结尾——你把它复制到某种缓冲区来做什么?你是什么意思“把它写回”文件。你的意思是它覆盖了文件,在init上截断为原始文件的500k字节+它添加了什么? 建议:
|
|
|
7
0
我认为这与计算机无关,但你们是如何写日志课的。我觉得很奇怪,你把最后500k读成一个字符串,你为什么要这样做? 只需追加到日志文件中。
|
|
|
8
0
Widefinder 2 has a lot of talk about efficient IO available (或者,更准确地说,“注释”列下的链接有很多关于高效IO的信息)。 回答您的问题:
在文件系统操作方面,标准库有点有限。如果你不局限于标准库,你可以很容易地提前结束一个文件(也就是说,“这一点之后的所有内容都不再是这个文件的一部分”),但很难延迟开始一个文件。 只需在文件中查找500000字节,然后启动一个新文件的缓冲副本,这将是有效的。但是一旦你做到了这一点,标准库就没有现成的“重命名此文件”功能。原生操作系统函数可以有效地重命名文件,Boost也是如此。文件系统或STLSoft。
在这种情况下,您将删除文件的最后一位,这在标准库之外很容易做到。只需使用文件系统操作将文件大小设置为500000字节(例如。,
|
|
|
Abdullah Chaudhry · json文件上的文件旋转和删除 3 年前 |
|
|
Max S · 如何从CMD读取日志的所有输出 8 年前 |
|
|
Ivan Denchev · Apache-过去一小时的日志 8 年前 |
|
|
ninja.coder · Log4j中的字符串串联性能 8 年前 |
|
|
Rich · 如何记录日志。是否与操作员一起调试? 8 年前 |