ファイル読み書きのロックについて

[戻る]
こっとん 2005/02/10(木) 23:20:39
いつもお世話になっています。

複数のPCからあるファイルサーバーにおいてあるデータファイルに対して読み書きをするプログ
ラムを組んでいます。
fp = fopen("\\\\192.168.1.200\\share\\data.dat","rb");
if(!fp)MessageBox("失敗");
といった感じです。
私の考えだと、fopenされてる間は他のマシンからもしアクセスがあったら開くことができず
fopenしてもNULLが返ると思っていました。
けれど実際に実験すると、あるマシンでファイルがオープンされてる間に他のマシンでオープン
するとなんなくできてしまい、読み書きができてしまいます。
これは非常に危険ですし、ロックをかけたいのですが調べたり、詳しい人に相談しても解決策が
わからずここで質問させていただくことにしました。
現時点でいきついた答えとしてはCreateFileというAPIを使えばロックできるのかもしれない
(さっきMSDNで確認しましたがそれらしき項目が見当たりませんでしたが)というのと、あと、
_lockfile()なるVCだけで使えるというあまり聞きなれない関数があるとか・・・。
Perlなどのようにロックする関数は存在しませんか?

なお、開発環境はVC++6.0、SP6適用済み、Win2000です。

通りすがり 2005/02/11(金) 02:26:03
本当にMSDNを確認しました?
第三引数によって共有モードを指定できますよ。
オープン中にも共有許可を与えるならフラグを立てる方式なので、0を渡して
ファイルをオープンすれば、排他ロックになります。

KING・王 2005/02/11(金) 08:13:50
少し古いですが、MSDNライブラリ2001年10月リリースのCreateFile()より
=========================================
HANDLE CreateFile(
  LPCTSTR lpFileName,                         // ファイル名
  DWORD dwDesiredAccess,                      // アクセスモード
  DWORD dwShareMode,                          // 共有モード
  LPSECURITY_ATTRIBUTES lpSecurityAttributes, // セキュリティ記述子
  DWORD dwCreationDisposition,                // 作成方法
  DWORD dwFlagsAndAttributes,                 // ファイル属性
  HANDLE hTemplateFile                        // テンプレートファイルのハンドル
);

(中略)

dwShareMode 
オブジェクトの共有方法を指定します。0 を指定すると、オブジェクトを共有できません。この
ハンドルを閉じない限り、それ以降にこのオブジェクトを開こうとしても失敗します。 

=========================================

ということで、通りすがりさんのおっしゃられるように第3引数にしっかり「共有モード」とい
う
引数が存在します。

また、_fsopen()なんて関数もありますので、一度調べてみては如何でしょうか?

こっとん 2005/02/12(土) 04:51:43
レスありがとうございます。
共有モードというのがよく読んだらファイルのロックにつながるものでした。
ざざっと読んでいたため(APIに期待していなかったためか・・・)見落としていました。
実際CreateFileで成功しました。
が・・・CreateFileで開いた場合、読み書きがWriteFile及びReadFileしかないようで、
ReadFileがとくに役不足に感じています。
fgetsのように1行(改行文字が出るまで)読むということを自動でしてもらうことになれてい
たため非常に扱いづらく感じています。
EOFも自動では検出してもらえないみたいだし・・・。
KING王さんのほのめかしてくれた_fsopen()というのをこれから調べてみようかと期待していま
す。
もしもAPIでfgets()のような便利な関数があるととても嬉しいのですが・・・。
ない場合は1字ずつReadFileして\nやEOFが出るまでバッファにコピーしていくという方法をと
らざるを得ないでしょうか?

アイススケーター 2005/02/12(土) 08:13:57
読み出すことを前提とすれば、テンポラリファイルにコピーしてから利用すれば
いいと思いますが。

シャノン 2005/02/12(土) 17:30:45
> ない場合は1字ずつReadFileして\nやEOFが出るまでバッファにコピーしていくという
> 方法をとらざるを得ないでしょうか?

ある程度読んでバッファに溜めて、バッファの中を走査して改行文字を探し、あれば
改行文字の前までを返し、なければさらに読み込みます。
改行文字が見つかった場合、次回の読み込み時には、まず前回読み取り分の改行文字
以降を追加しなければならない点にご注意ください。

古いスレッドには追加発言できません。