我们的日志记录类在初始化时将日志文件截断为500,000字节.从那时起,日志语句将附加到文件中.
我们这样做是为了保持低磁盘使用率,我们是商品最终用户产品.
显然保留前500,000个字节是没用的,所以我们保留最后500,000个字节.
我们的解决方案存在严重的性能问题 有效的方法是什么?
"我可能会创建一个新文件,在旧文件中搜索,从旧文件到新文件进行缓冲读/写,将旧文件重命名为旧文件."
我认为你会变得更好:
#includestd::ifstream ifs("logfile"); //One call to start it all. . . ifs.seekg(-512000, std::ios_base::end); // One call to find it. . . char tmpBuffer[512000]; ifs.read(tmpBuffer, 512000); //One call to read it all. . . ifs.close(); std::ofstream ofs("logfile", ios::trunc); ofs.write(tmpBuffer, 512000); //And to the FS bind it.
这可以通过简单地将最后的512K复制到缓冲区,以截断模式打开日志文件(清除日志文件的内容),然后将相同的512K反射到文件的开头来避免文件重命名.
请注意,上面的代码尚未经过测试,但我认为这个想法应该是合理的.
您可以将512K加载到内存中的缓冲区中,关闭输入流,然后打开输出流; 这样,你就不需要两个文件,因为你输入,关闭,打开,输出512个字节,然后去.您可以通过这种方式避免重命名/文件重定位魔术.
如果你不厌恶在某种程度上将C与C++混合,你或许也可以:
(注意:伪代码;我不记得mmap调用了我的头脑)
int myfd = open("mylog", O_RDONLY); // Grab a file descriptor (char *) myptr = mmap(mylog, myfd, filesize - 512000) // mmap the last 512K std::string mystr(myptr, 512000) // pull 512K from our mmap'd buffer and load it directly into the std::string munmap(mylog, 512000); //Unmap the file close(myfd); // Close the file descriptor
根据许多事情,mmap 可能比寻求更快.如果你好奇,谷歌搜索'fseek vs mmap'会产生一些有趣的阅读.
HTH