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

解決


crow  2011-05-31 23:30:10  No: 40581

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-06-01 00:26:14  No: 40582

> Serverの「fmCreate or fmShareDenyWrite 」

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

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


crow  2011-06-01 00:48:00  No: 40583

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

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

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


au  2011-06-01 01:53:15  No: 40584

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


crow  2011-06-01 02:07:31  No: 40585

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

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

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


au  2011-06-01 04:25:38  No: 40586

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

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


crow  2011-06-01 05:21:58  No: 40587

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


tor  2011-06-01 07:33:51  No: 40588

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


KHE00221  2011-06-01 11:13:29  No: 40589

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


crow  2011-06-01 19:47:54  No: 40590

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

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


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加