2012-01-08 34 views
4

私はマルチスレッドアプリケーションを開発しています。私は私のコードのどこかに持っている:二行目は時々罰金と他の回を実行しますC#ファイルの移動と上書き

File.Delete(sidetapedata); 
File.Move(sidetapedata2, sidetapedata); //sidetapedata and sidetapedata2 are two file paths that correspond to sidetapedata.txt and sidetaptdata2.txt in some directory. 

、それがスローIOException

Cannot create a file when that file already exists. 

sidetapedataファイルが、その1つにアクセスされる1件の以上のスレッドがありますこのファイルのみを読み取り、書き込み操作はしません。競合状態を保護するためにロックを使用しています。なぜこれが起こっているのか分かりません。

UPDATE:ビジュアルC#デバッガは、これらのファイルを含むディレクトリに探して、私は、この例外を示していた場合であっても、私が見る何sidetapedata.txtファイルはありませんが、sidetapedata2.txtファイルがあります!

アップデート2sidetapedata.txtsidetapedata2.txtが、それはありません意味Deleteコールして、ファイルシステムで起動いくつかのイベントがありますしない限り、これが起こる理由を必ず空白

+5

FileStreamを使用し、Windowsの/ウイルス対策/など、時々ファイル「が存在」Windowsを尋ねた後、しばらくはそれを削除することを確認します。 –

答えて

7

両方されていない場合にも、この動作がのみ発生実際にはが削除されます。いくつかのオプション:

  • あなたは可能性がありますが、動きをしようとする前に、ファイルの存在をチェックし、それはまだあなたは
  • 削除後に存在する場合は簡単に寝る(erroring前のループの最大数のいくつかの並べ替えを持つ)ループ移動する代わりにFile.Copy(sidetapedata, sidetapedata2, true)コピーを使用し、ソースファイルを削除することができます。しかし、単純なファイルシステムのディレクトリエントリの変更(実際にデータをコピーするのではなく)で移動が処理されると仮定すると、効率は低下します。
  • の代わりにFile.Moveをターゲットファイルに使用して、その後、MoveDeleteよりもアトミックであることを期待して、それを削除してください。

I 容疑者スレッドは、ここでは関係ありません - 私はあなたがそれを除外(と簡単に回避策をテストする)ことができますので、あなたが、それを検証する短いが、完全なプログラムを書く示唆しています。

+0

あなたの答えは妥当性検査が必要ではありませんが、削除した後すぐにThread.Sleepを使用するのは正しいです。これは私のための単一のスレッドアプリで同様の問題を修正しました。乾杯。 – tbone

3

これは、.NETでも同じですが、Win32のDeleteFile APIリファレンスに応じた場合、私はわからないよ:

DeleteFileを機能が密接に削除するファイルをマークします。したがって、ファイルの最後のハンドルが閉じられるまで、ファイルの削除は行われません。

したがって、削除の呼び出しとファイルの最後のハンドルを閉じるWindowsとの間には時間があります。あなたはこの期間中にMoveに電話しているようです。

0

このanswerを1として:それを削除する前に、ファイルの名前を変更しFileShare

FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None); 
関連する問題