ファイルアクションfopen,fopen_s,_fsopen


最近のプログラムでファイルを開くときに失敗しました.最後のコードの問題は次のとおりです.
  fopen_s(&pFile,strPath.c_str(),"rb+");
主に「rb+」です.
まず紹介しますが、主にwindows下のCRT関連のファイルオープン操作です.
C 89規格ではfopen:
FILE * fopen(const char *file, const char *mode);
Windowsにfopen_がありますs,_fsopenの拡張:
errno_t fopen_s(    FILE** pFile,   const char *filename,   const char *mode );
FILE *_fsopen(    const char *filename,   const char *mode,   int shflag );
vs 2008/2010 CRTのソースコードを見るとfopen、fopenが見えます.sはすべて呼び出しによって_fsopenが実現する:
FILE * fopen(const char *file, const char *mode)
{
    return( _fsopen(file, mode, _SH_DENYNO) );
}

errno_t fopen_s(FILE ** pfile, const char *file, const char *mode)
{
    _VALIDATE_RETURN_ERRCODE((pfile != NULL), EINVAL);
    *pfile = _fsopen(file, mode, _SH_SECURE);

    if(*pfile != NULL)
        return 0;
    return errno;
}

主に_fsopenの3番目のパラメータ:int shflag:
#define _SH_DENYRW      0x10    /* deny read/write mode */
#define _SH_DENYWR      0x20    /* deny write mode */
#define _SH_DENYRD      0x30    /* deny read mode */
#define _SH_DENYNO      0x40    /* deny none mode */
#define _SH_SECURE      0x80    /* secure mode */

ソースコードから分かるように、いわゆる_SH_SECUREは/*share read access only if read-only*/
だから違いはfopenが_SH_DENYNOは読み書きを共有し、fopen_sは_SH_SECUREは読み取り専用モードでのみ共有され、他の場合は共有されません.
最初の質問に戻りますが、ファイルの読み取りに失敗したのは、いくつかのプロセスが同時にこのファイルを読んでいるためで、モードは「rb+」で開いているのは読み取りと書き込みのためなのでfopen_sは1つのプロセスにロックされ、他のプロセスに共有されません.解決策は「rb+」を「rb」すなわち読み取り専用モードに変更すればよい.
まとめ:ファイルを開くときは、できるだけ読み書きマークを減らすことができます.特に、読み取り専用であればいい場合が多いので、書き込み可能にしないでください.