2

Cには2つのプロジェクトがあります。

最初:

include windows.h
include stdio.h
include tchar.h

int main()
{
     HANDLE hFile = CreateFile("D:\\f.txt",
    GENERIC_WRITE,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);

    if(hFile == INVALID_HANDLE_VALUE)
        _tprintf("Error: CreateFile %d\n",GetLastError());

    Sleep(5000);

    return 0;
}

二番目:

include windows.h
include stdio.h
include tchar.h

int main()
{
     HANDLE hFile = CreateFile("D:\\f.txt",
    GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);

if(hFile == INVALID_HANDLE_VALUE)
    _tprintf("Error: CreateFile %d\n",GetLastError());

            return 0;
}

最初のプログラムは、他の人がファイルから読み取れるようにしながら、ファイルを開いて読み取ることになっています。2つ目は、読み取り用にファイルを開くことになっています。

プログラムを実行すると、2番目のプログラムでエラー32(ERROR_SHARING_VIOLATION)が発生します。

FILE_SHARE_READの全体的なポイントは、ファイルが既に開いているかどうかに関係なく、他のスレッド/プロセスが読み取りのためだけにファイルを開くことができるようにすることだと思いました。

誰かが私がこの問題を解決するのを手伝ってもらえますか?

PSファイルがメールスロットだった場合、それは何か違いがありますか?

4

3 に答える 3

8

CreateFile()呼び出しは、書き込み共有を明示的に拒否します。FILE_SHARE_READを指定しました。それは機能しません。最初のプログラムはGENERIC_WRITEを使用していたため、すでに書き込みアクセス権を取得しています。すでに取得されている権利を拒否することはできないため、共有違反エラーで通話が失敗します。

これを機能させるには、2番目の呼び出しで代わりにFILE_SHARE_WRITEを指定する必要があります。そして、予測できない時間と場所で書き込まれているファイルから読み込もうとするという頭痛の種に対処します。これは通常、最初のプロセスがファイルに追加するだけでシークしない場合にのみ適切に終了します。また、追加されたデータの一部がまだバッファに残っているか、書き込まれているために、データの一部しか取得されない場合があります。トリッキーなもの。それが問題である場合は、メッセージモードのパイプを検討してください。

コメントから繰り返しますが、共有フラグは、ユーザーが実行できることを制御するのではなく、別のプロセスがファイルに対して実行できることを制御します。やりたいことは2番目の引数で指定します。したがって、FILE_SHARE_WRITEが欠落していると、別のプロセスがファイルに書き込むことができなくなるため、問題になります。しかし、それはすでにあります。

于 2012-05-06T19:45:04.737 に答える
3

ハンドルが開いている既存のリクエストで指定されているアクセスモードと競合する共有モードをリクエストすることはできません。CreateFileは失敗し、GetLastError関数はERROR_SHARING_VIOLATIONを返します。

ここで最初のプログラムでは、3番目のパラメーター(dwShareMode)を他のプロセスに「読み取り」アクセス許可を付与するものとして指定し、2番目のパラメーター(dwDesiredAccess)でそれ自体の「書き込み」アクセスを要求します。

次に、2番目のプログラムで、2番目のパラメーターで「読み取り」アクセスを要求し(これは問題ありません)、3番目のパラメーターで他のプロセスに「読み取り」権限のみを付与します。これは最初のプログラムで指定されたアクセスモードと競合します(「書きます")。最初のプログラムによるファイルのオープンは、「ハンドルが開いている既存のリクエスト」です。

最初のプログラムでは、「私は「f.txt」に書き込むことができます。他の人はそれを読むことしかできません」と言っています。2番目のプログラムでは、「私は「f.txt」を読むことができます。他の人はそれしか読むことができません。」と言っています。これは、最初のプログラムがすでに「f.txt」に書き込んでいるため、矛盾しています。

すでに述べたように、2つの異なるプロセスによるファイルの読み取りと書き込みは、データ破損の良いレシピです。

于 2012-05-07T18:09:00.923 に答える
1

CreateFileドキュメントの答えは次のとおりです。

ハンドルが開いている既存のリクエストで指定されているアクセスモードと競合する共有モードをリクエストすることはできません。CreateFileは失敗し、GetLastError関数はERROR_SHARING_VIOLATIONを返します。

つまり、ファイルを開いて書き込みますが、この書き込みを共有できることを示していません。

于 2012-05-06T19:22:32.523 に答える