- PR -

ファイルが他プロセスから読書き禁止で開かれているかどうかをチェックする方法

投稿者投稿内容
TAM
会議室デビュー日: 2006/11/16
投稿数: 3
投稿日時: 2006-11-16 16:21
C#を使って「ファイルが他プロセスから読書き禁止で開かれているかどうか」をチェックする
方法を探しています。

現在のところは、FileStreamの生成箇所をtry-catchで捕捉し、

(チェックするファイルを仮に「ファイルA」として)
1.ファイルAが存在するかどうかをチェックする。
2.存在しない場合はファイルAのパスを指定してFileStreamの生成を試みる。
3.生成ができずにIOExceptionがthrowされてきた場合は、排他的に開かれていると
判断する。

という方法で実装しようと考えています。
(補足ですが、ファイルAはLAN環境下の複数端末で共有されるファイルであるため、
Mutexを使っての制御は不可能と判断しました。)

しかし、IOExceptionクラスにエラーの発生原因を特定できる材料が乏しく、
他プロセスから読書き禁止で開かれているために例外が発生したとは言い切れないため、
もっと良い方法がないかを探しています。

どなたかご教示いただけますでしょうか。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-11-16 16:31
引用:

TAMさんの書き込み (2006-11-16 16:21) より:

C#を使って「ファイルが他プロセスから読書き禁止で開かれているかどうか」をチェックする方法を探しています。


この手の質問は何度も見てきていますが、基本的には例外処理でしか無理です。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-11-16 22:53
1.ファイルの有無を調べる
1.ある場合:
 2.権利を調べる
 2.読み書きの権利がある場合:
  開けなかったら誰かが排他ロックしている
 2.権利がない場合:
  権利がないので、開こうとする前に例外が発生することがわかる
1.ない場合:
 3.書き出そうとするディレクトリの権利を調べる
 3.書き込み権がある場合:
  作成できなかったら、タッチの差で誰かが作った
 3.書き込み権がない場合:
  作成しなくても、例外が発生することがわかる


 もっとも、ファイルがあると判断してから open するまでの間に誰かが消したらどうする?とか、タイミング上の問題はいろいろある。
 例外が発生してから調べるのではなく、例外を発生させないように調べてください。
_________________
ちゃっぴ
ぬし
会議室デビュー日: 2004/12/10
投稿数: 873
投稿日時: 2006-11-17 00:22
引用:

Jittaさんの書き込み (2006-11-16 22:53) より:
 例外が発生してから調べるのではなく、例外を発生させないように調べてください。



これ trap 可能な例外が発生するか否かで変わってくるような・・・

確実に trap 可能な例外が発生するとわかっているならば、むしろそれを有効に活用するほうが正しいような気がします。
そうしておけば、timing の問題も解決できるわけでして。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2006-11-17 08:27
引用:

TAMさんの書き込み (2006-11-16 16:21) より:
しかし、IOExceptionクラスにエラーの発生原因を特定できる材料が乏しく、
他プロセスから読書き禁止で開かれているために例外が発生したとは言い切れないため、
もっと良い方法がないかを探しています。


FileStream生成時に発生する例外はIOExceptionだけでは無いでしょ。アクセス権の不足に理由があった場合には、SecurityExceptionやUnauthorizedAccessExceptionが発生しそうな気がします。実際にロックした状態で開いて、どんな例外が発生するか確認しましたか?

私もちゃっぴさんの意見に賛同。
引用:

Jittaさんの書き込み (2006-11-16 22:53) より:
もっとも、ファイルがあると判断してから open するまでの間に誰かが消したらどうする?とか、タイミング上の問題はいろいろある。


と言う部分に対応するには、結局例外処理でトラップせざる得ないです。事前判断によるトラップと、例外処理によるトラップを二重に作成することになり、無駄にコードを増やすと同時に、バグの温床にもなります。

かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2006-11-17 09:17
引用:

ちゃっぴさんの書き込み (2006-11-17 00:22) より:

確実に trap 可能な例外が発生するとわかっているならば、むしろそれを有効に活用するほうが正しいような気がします。
そうしておけば、timing の問題も解決できるわけでして。


例外処理は、最適化をかけることができない重い処理なので、例外を発生しないですむのなら、発生させないようにしたほうがいい。

というようなことが、Effective Javaに書かれてた。

.NET上でも、同じことが言えるかどうかは分からないけどね。

追加:
甕星さんの読んでなかった。

結局、どうがんばっても例外が発生してしまうのなら、やっぱ例外処理で対処した方がいいかもね。
上で書いたのは、例外を発生しなくでも対処できる方法があるにもかかわらず、例外処理で対処してしまう場合として捉えてください。

[ メッセージ編集済み 編集者: かずくん 編集日時 2006-11-17 09:23 ]
TAM
会議室デビュー日: 2006/11/16
投稿数: 3
投稿日時: 2006-11-17 10:50
多数のご返信ありがとうございます。

最初の書込みの際に前提が抜けていたようなので補足させてください。
ファイルAは特定のメニューが実行されていることを他の端末に対して知らせるための
ファイル(アクセス権は読取専用で作る予定)で、メニュー起動時に作成して開き、
メニューが閉じればファイルAも閉じられて削除される仕様です。

引用:

甕星さんの書き込み (2006-11-17 08:27) より:
FileStream生成時に発生する例外はIOExceptionだけでは無いでしょ。アクセス権の不足に理由があった場合には、SecurityExceptionやUnauthorizedAccessExceptionが発生しそうな気がします。実際にロックした状態で開いて、どんな例外が発生するか確認しましたか?


FileStream生成時に発生する例外にはIOException以外に

・FileNotFoundException
・UnauthorizedAccessException

があるようなので、事前にファイルの存在チェックと
Jittaさんが仰るようにディレクトリへの権限チェックを行なえば、意図しない理由での
例外発生をおさえられるように思います。

アドバイスありがとうございました。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2006-11-17 10:51
引用:

かずくんさんの書き込み (2006-11-17 09:17) より:
というようなことが、Effective Javaに書かれてた。


Javaの場合には実際に例外が発生しない限り、オーバーヘッドは無視できるレベルにとどまるそうです。したがって例外が発生するのが、例外的な(稀な)状況なら、例外処理を使ってもパフォーマンスを問題にする必要はなさそうです。

引用:

.NET上でも、同じことが言えるかどうかは分からないけどね。


.NETでは問題ないそうです。例外処理で問題となるオブジェクトのクリーンアップは、finallyでプログラマが面倒を見ることになっているので当然かもしれません。
http://www.microsoft.com/japan/msdn/columns/csharp/csharp07192001.aspx

ちなみにC++の場合Tryブロックを記述しただけでオーバーヘッドが発生します。・・・が、プログラムの品質よりも、実行速度を優先すべき明確な理由がないなら「例外使っておきなよ」と思いますね。

スキルアップ/キャリアアップ(JOB@IT)