0

我有一个带有日志行的日志文件。每行由时间戳和消息组成。

timestamp1 blablabla  
timestamp2 foo  
timestamp3 bar  
etc...

我的班级LogFile有一个地图作为成员,以将每个时间戳与 ifstream 位置相匹配。
现在我想在这些时间戳上创建一个自定义迭代器。

例子 :

LogFile myFile("file.log");  
for (LogFile::iterator it = myFile.begin(); it != myFile.end(); it++)  
    std::cout << it->message << std::endl;

输出 :

blablabla  
foo  
bar 

我还希望迭代器能够递减。

现在我真的不知道如何以有效的方式实现它。

最简单的方法是使用每个迭代器增量打开-查找-读取-关闭文件。但这有效吗?我读到打开/搜索/关闭非常昂贵。

也许更好的解决方案是有一个LogFile::open()方法来打开文件,让它保持打开状态来做我们想要的所有增量,最后用一个LogFile::close()方法关闭文件。

你对此有什么建议吗?我敢肯定这不是第一次有人必须处理这种问题。

编辑更多细节:

我的类 LogFile 有一个类型的成员,std::map<Time, std::streampos>用于存储时间戳和流位置之间的链接。
我需要增加减少迭代器。因此我认为地图会更合适,因为我会使用the std::map::find(Time)很多(复杂度 o(log(n)),而不是std::vector::find(Time)ao(n) 复杂度)。

日志文件非常大(~20Mo),我的应用程序必须在资源有限的嵌入式系统上运行。所以我不能将整个文件存储在内存中,我必须在给定的时间缓冲并只获取我需要的部分。

所以是的,我想我会处理“open() and close() once”方法。

在增量的情况下,我不需要std::ifstream::seekg()很多。但是在递减的情况下,我看不到另一种方法来寻找每个时间戳。这真的是最好的方法吗?

4

3 回答 3

0

除非必要,否则我肯定会避免打开和关闭文件。在构造函数中打开文件,LogFile在析构函数中关闭它。

于 2013-08-27T11:10:50.600 回答
0

我不知道您的确切用例,但在我看来,使用地图存储这些数据似乎是多余的。我认为您不会使用确切的时间戳来查询此地图,对吗?而且我假设日志文件条目已经在源日志文件中按时间排序,因此当读入向量时,它们也会被排序。我的建议是,使用包含时间戳对和 ifstream 位置的向量。

只要使用文件的 LogFile 实例存在,我肯定会建议保持文件打开。这样,当有人使用迭代器按顺序访问条目时,您将节省大量时间,因为会减少查找次数。

如果日志文件不是太大,我还建议将文件中的所有条目读取到内存中,这样可以节省时间,否则会因所有 i/o 操作而丢失。

于 2013-08-27T11:18:09.473 回答
0

可能值得尝试使用映射您的文件,mmap然后使用madvise手动使可能很快访问的页面留在内存中。

于 2017-02-25T20:28:00.417 回答