2012-02-06 7 views
1

私は電源障害の中間書き込みの場合でも、ファイルにアトミックに追加する手段を提供するC++でクラスを作成しようとしています。ftruncate()は非同期ですか?

まず、現在のファイル位置(ファイルの先頭からバイト単位で64オフセット)を別のジャーナルファイルに書き込みます。次に、要求されたデータを日付ファイルの最後に書き込みます。最後に、ジャーナル・ファイルのftruncate()(切り捨てられたサイズを0に設定)を呼び出します。

主な考え方は、このクラスが空のジャーナルファイルを含むファイルを開くよう依頼された場合、書き込みが中断されたことを知っており、ジャーナルファイルとfseekからの最後の書き込みの位置を読み取ることができますその場所に。最後の部分書き込みは失われますが、ファイルは破損してはいけません。

残念ながら、ftruncate()は非同期です。実際には、ftruncateの後にfflush()とfsync()を呼び出しても、たくさんの書き込みを行っているうちにジャーナルが数百バイトにまで増加することがわかります。それはいつも最終的に0に終わるが、私はそれを常に0または8のサイズで見ることを期待していた。

ftruncateを完全に同期させることは可能ですか?それともジャーナルを使う良い方法はありますか?

+0

電源障害ですか? –

+0

ジャーナルを回復している間に電源が再び落ちるとどうなりますか? –

+1

"ジャーナルを使う良い方法はありますか?" - あなたの回復要件に依存します。いくつかの "次ブロックのNバイト"メッセージをデータファイルに書き込むと、別のジャーナル(および磁気HDDで遅いヘッドの再配置)が不要になります。ブロックの先頭からファイルを再走査したり、ブロックの最後から逆方向に走査するときに、次のブロックNバイトのコンテンツを他のコンテンツと区別することができます。メモリマッピングはおそらくジャーナルのためのもう少しエレガントです。 –

答えて

4

ftruncate()ファイル内のファイル記述子の書き込みオフセットは変更されません。ファイルを開いたままにして、ftruncate()を呼び出した後に次の長さを書き込むと、ファイルのオフセットがまだ増加しています。書き込むと、ファイルの長さがオフセットにリセットされ、そこにバイトが書き込まれます。

ftruncate()を呼び出した後、おそらくあなたがしたいことは、ファイルの次の書き込みがファイルの先頭で行われるようにして、lseek(fd, 0, SEEK_SET)と呼び出してください。

+0

は魅力的に働いた。 :)ありがとう! – dicroce

+0

それは私にも働いた! – amc

関連する問題