2012-03-19 9 views
1

大まかに言えば、アプリケーションの状態を含むファイルがあります。同じスレッドで読み取り/書き込み/書き込み/切り捨て機能を維持したままファイルをロックしますか?

私は次のような動作を実装します:アプリケーションが起動されると、他のアプリケーション(またはユーザー自身)ようにファイルをロック

  • はそれを変更することができるようになります。
  • ファイルから前のアプリケーション状態を読み取ります。
  • ... do work ...
  • ファイルを新しい状態で更新します(ファイルの書式では、ファイル全体を書き換えますが、操作後にファイルの長さが短くなる場合があります)。
  • ...仕事を...
  • もう一度
  • をファイルを更新...作業を行う...
  • 仕事は(アプリケーションがクラッシュした)失敗した場合は、ロックが外され、およびコンテンツ以前の作業単位が実行された後の状態になります。

ファイルを書き換えるには、Truncateオプションを使用してファイルを開く必要があります。つまり、ファイルを書き換えるたびに新しいFileStreamを開く必要があります。 ;その後、がFileShare.ReadFileStreamを開く、ファイルを読み込むと、アプリケーションが起動されると

  • :だから、私が欲しいという行動が唯一、このような汚い方法によって達成できたようです
  • 作業が完了したら、前に開いたハンドルを閉じ、別のFileStreamFileMode.TruncateFileShare.Readで開き、データを書き込み、FileStreamをフラッシュします。
  • 作業が完了したら、前に開いたハンドルを閉じ、別のFileStreamFileMode.TruncateFileShare.Readで開き、データを書き込み、FileStreamをフラッシュします。
  • Disposeには、以前に開いたハンドルを閉じます。

このようなやり方にはいくつかの欠点があります。余分なFileStreamが開かれます。ファイルの完全性は、FileStreamが閉じてからFileStreamが開かれるまで保証されません。コードははるかに複雑です。 これらの欠点がない他の方法はありますか?

答えて

2

ファイルを閉じてから再度開かないでください。代わりに、FileStream.SetLength(0)を使用して、ファイルを書き換えたいときにゼロの長さに切り捨てます。

また、FileStream.Positionを0に設定する必要があります(またはしない場合もあります)。このドキュメントでは、SetLengthがファイルポインタを移動するかどうかを明確にしていません。

+0

'FileStream.SetLength'はまさに私が探していたものです! – penartur

0

アプリケーションの起動時にファイルへの排他アクセスをして、実際のファイルがOS用にロックされたままで、プロセス内のすべてのスレッドで共有できるファイルのインメモリキャッシュを作成するのはなぜですか。 lock(memoryStream)を使用すると、並行性の問題を避けることができます。ローカルのメモリ内バージョンのファイルの更新が完了したら、ディスク上のファイルを更新してロックを解除するだけです。

よろしくお願いいたします。

+0

質問を誤解しているようです。私はそれぞれの_checkpoint_で "ディスク上のファイルを更新する"ようにします(アプリケーションが後でクラッシュすると、最新のチェックポイントまでのすべてのデータがディスクに保存されるようになります)。問題は、ロック解除せずにファイルを何回書き直すことができますか?問題は、実際にはスレッディングとは関係がありません。私はちょうどそのような方法で質問を述べることが理解しやすくなると思った。 – penartur

+0

申し訳ありませんが、あなたの質問のタイトルを誤解しました。定期的にディスク上のファイルに更新をプッシュしたいが、実際にプロセスを実行している間に他のプロセスがファイルを変更しないようにファイルのロックを解放したいとは思わない? –

+0

はい、そうです。また、_update_は既存のファイルに追加するのではなく、新しいコンテンツが元のファイルよりも短くなるように、ファイルの内容全体を書き換えます。 – penartur

関連する問題