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()メソッドでファイルを閉じることです。

これに関するヒントはありますか?誰かがこの種の問題に対処しなければならないのはこれが初めてではないと確信しています。

EDITいくつかの詳細:

私のクラス LogFile には、std::map<Time, std::streampos>タイムスタンプとストリーム位置の間のリンクを保存するために type のメンバーがあります。イテレータをインクリメントおよび
デクリメント する必要があります。したがって、私は多くのことを使用するので、マップの方が適切だと思います( ao(n)の複雑さではなく、複雑さo(log(n)) )。the std::map::find(Time)std::vector::find(Time)

ログ ファイルは非常に大きく (~20Mo)、アプリケーションは限られたリソースの組み込みシステムで実行する必要があります。そのため、ファイル全体を RAM に保存することはできません。バッファリングして、特定の時間に必要な部分だけを取得する必要があります。

そうです、私は「open() and close() once」メソッドを扱うつもりだと思います。

インクリメントの場合std::ifstream::seekg()、多くする必要はありません。しかし、デクリメントの場合、タイムスタンプごとにシークする別の方法がわかりません。それは本当に最善の方法ですか?

4

3 に答える 3

0

必要でない限り、ファイルを開いたり閉じたりすることは絶対に避けます。コンストラクタでファイルを開き、LogFileデストラクタで閉じます。

于 2013-08-27T11:10:50.600 に答える