Delphi2005 でファイルの排他アクセス

解決


crow  2011-05-31 14:30:10  No: 40581  IP: 192.*.*.*

ServerとClientの2つのソフトがあります。

ここでServerが作成したファイルをClientがかなりの頻度で読込みを行うのですが
ときどきプロセスが使用中ですとServerがWriteできない時があり困っています。
Server側[*]の所でわざとブレークさせている最中だと現象が確認しやすかったのでこれで実験しています。
このServerがブレーク中でもClientではファイルに読取専用でいいのでアクセスするにはどうしたらいいのでしょうか?

Serverの「fmCreate or fmShareDenyWrite 」
Clientの「fmOpenRead」
の組み合わせではなぜだめなのでしょうか?
<Server側処理>
  fs := TFileStream.Create(Str_InifileName, fmCreate or fmShareDenyWrite );
* Str := 'ABCD';
  fs.Write(PChar(Str)^, Length(Str));
  finally
  fs.Free;

<Client側処理>一旦ロードし別ファイルに同じ内容を保存したいのです。

  SF:=TFileStream.Create(Str_CommServerFilePath,fmOpenRead);
  sz:=SF.Size;
  getmem(buf,sz);
  SF.Read(buf^,sz);

  SF.Free;
  DF:=TFileStream.Create(Str_CopyFilePath,fmCreate);
  DF.Write(buf^,sz);
  DF.Free;
  freemem(buf);

編集 削除
tor  2011-05-31 15:26:14  No: 40582  IP: 192.*.*.*

> Serverの「fmCreate or fmShareDenyWrite 」

CreateのモードにfmCreateが含まれていると、他のフラグを一緒に指定しても無視されます。
(ヘルプでファイルオープンモード定数を調べるとわかりますが
fmCreateの値は$FFFFなので、他の定数をorしても結局fmCreateと同じ値になります)

新規ファイルを共有モードで作りたい場合、一度ファイルを作ってから
改めて共有モードを指定して開きなおすという格好悪いことをしないといけないようです。

編集 削除
crow  2011-05-31 15:48:00  No: 40583  IP: 192.*.*.*

貴重なアドバイスありがとうございます。
fmCreateのせいでほかのフラグが無意味になることはよくわかりました。
なので既存ファイルがあるものという前提ですが、Server側の処理を

  fs := TFileStream.Create(Str_InifileName, fmShareDenyWrite );

にしたのですが、やはりClientではTFileStream.Createの行でエラーが発生しプロセスが使用中とのダイアログがでます。
まだなにかいけないのでしょうか?

編集 削除
au  2011-05-31 16:53:15  No: 40584  IP: 192.*.*.*

クライアント側で開く場合にも共有モードを指定しないと排他モードでファイルを開こうとするからエラーになっているのでしょう。

編集 削除
crow  2011-05-31 17:07:31  No: 40585  IP: 192.*.*.*

au様
アドバイス通りClientの処理を下記のようにしてみました。
エラーはでなくなりました。
 SF:=TFileStream.Create(Str_CommServerFilePath,fmShareDenyWrite);

Serverからはどんどん最新情報が書かれるので「fmShareDenyWrite」にしました。
目的としては何度読んでもClientではエラーがでず、読んだ時点のデータが上がってくればいい、Serverからの最新情報が間に合わなければ次回読込み時でもよいというかんじです。

これで間違った指定ではないでしょうか?

編集 削除
au  2011-05-31 19:25:38  No: 40586  IP: 192.*.*.*

fmShareDenyWriteを指定すると、書き込みアクセスを禁止する事になるのでクライアント側が先にファイルを開くとサーバープログラムが書き込み出来なくなると思います。

クライアント側はfmShareDenyNoneを指定したらいいんじゃないでしょうか

編集 削除
crow  2011-05-31 20:21:58  No: 40587  IP: 192.*.*.*

度々すみません。
クライアント側はfmShareDenyNoneにとのことなのでやってみましたが
よくよく見てみるとServerで保存しているはずのファイルがエラーはでないものの、更新されないことがあるようです・・・

編集 削除
tor  2011-05-31 22:33:51  No: 40588  IP: 192.*.*.*

ファイルオープンモードを指定する時には
まずオープンモードのいずれかを指定して、追加で共有モードのいずれかを指定するわけで
オープンモードを何も指定しなかったら fmOpenRead($0000) 相当になると思うんですが、それでちゃんと書けるんでしょうか?

編集 削除
KHE00221  2011-06-01 02:13:29  No: 40589  IP: 192.*.*.*

サーバ側を
fmOpenWrite or fmShareDenyWrite
クライアント側を
fmOpenRead or fmShareDenyRead

編集 削除
crow  2011-06-01 10:47:54  No: 40590  IP: 192.*.*.*

なるほど〜!
fmOpenWrite or fmShareDenyWrite
というor指定でできるんですね。

どうやらうまくいったようです。
大変助かりました!

編集 削除