最近程序中打开文件时,失败了,最后代码问题在:
fopen_s(&pFile,strPath.c_str(),"rb+");
主要是"rb+"。
首先来看下介绍,主要是windows下的CRT相关的文件打开操作了。
C89标准中是 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
);
通过看vs2008/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会被一个进程锁住,不共享给其他进程。解决方案就是将"rb+"改成"rb"即只读模式,就可以了。
总结:打开文件时,能尽量减少读写标志就尽量减少,尤其是很多时候只需要只读就可以了,就不要加可写。
时间: 2024-11-02 13:33:47