2016-08-10 10 views
0

使用シナリオは工業用(不安定な電源装置やその他のバグの多いプログラム/ハードウェア)です。電源が切れているとき(またはブルースクリーンクラッシュ時)にプログラムが影響を受けないようにする必要があります。 OSはNTFSのWindows 7です。ofstream(モードios :: out)は、システム停止時に既存のファイルを消去します。

私はboost :: property_tree write jsonを使用して、人が読めるテキストファイルにパラメータを記録します。

boost::property_tree::write_json("logic.txt", pt); 

実際にシステムが停止すると、「logic.txt」がワイプされました。 私はブーストソースファイルを読み込み、write_jsonコールは、デフォルトのiosでofstreamの::うち

std::basic_ofstream<typename Ptree::key_type::value_type> stream(filename.c_str());   

問題は、既存のファイルを拭きofstreamのこと、システムに障害が発生したときに空のファイルを残しする必要があります。

これはofstreamの既知の問題ですか?これに最も適した解決策は何ですか?終了したら「logic_tmp.txt」にまず、logic.txtする「logic.txt」を削除し、一時ファイルの名前を変更

  1. 書き込みファイル: は、私はいくつか考えることができます。

  2. ファイルに直接書き込むのではなく、SQLiteを使用します。 (MySQLは何度か壊れました。テーブルを再起動すると "修復"する必要があります)。

任意の提案が参考になります。

+0

「誰もがファイルIOを正しく取得しない方法」https://www.flamingspork.com/talks/(http://ids.cs/files/IO_Safety)を参照してください。 .gog) – sehe

+0

@面白い話、私は複数のSQLite(大規模なファイルを避け、競争を最小限に抑える)と仮定して、 'force flush'を使うと便利です。 – Guangyu

答えて

0

あなたの#1は、一時ファイルに書き込んでから名前を変更することです。ただし、リネームがアトミックであるためには、一時ファイルは同じファイルシステム上にある必要があります。最も安全なのは、単に同じディレクトリに格納することです。もちろん、mkstemp()などを使用して、固有の一時ファイル名があることを確認することもできます。

これは、ファイルシステムのセマンティクス(使用しているファイルシステムを教えてくれなかったため)に依存するため、考えられるすべてのシステムではまだ100%保証されていません。

もっと弾力のあるソリューションが必要な場合は、#2を使用することをお勧めします.SQLiteを使用します。あなたのように多くのシナリオでテストされています。 https://www.sqlite.org/testing.html

+0

あなたの提案をありがとう。これらのシステムはWindows 7でNTFSで動作しますが、ファイルシステムのセマンティクスについて詳しく説明できますか? – Guangyu

+0

NTFSでは、tempfileソリューションは問題ありません。具体的には、FATのようないくつかのファイルシステムは、電力損失などで本質的に失敗してしまいますが、そのうちの1つを使用していないので、心配しないでください。 –

関連する問題