C/C++打开文件

C/C++ 打开文件

一,问题

最近改了很久的一个转换资源的小工具的bug,最后发现原因是在判断文件是否存在时,fopen_s返回了错误,程序认为该文件并不存在,因而并未对该资源进行转换。
fopen_s返回错误码32 即 Broken Pipe; 以前常用fopen_s/fopen判断文件是否存在,也未考虑可能出现的问题,由于采用多线程转换,所以可能会由于fopen_s频繁打开关闭文件,而部分句柄忘记关闭导致,后来资源管理器检查之后发现所有文件句柄均正常关闭。最后

C++常用方法

ifstream fin("test.txt");
if (!fin)
{
   std::cout << "can not open this file" << endl;
}

C语言常用方法

//方法1

File* fh = fopen("test.txt","r");
if(fh == NULL)
{
   printf("%s","can not open the file");
}
//方法2使用access()
//函数定义
int _access( 
   const char *path, 
   int mode 
);
//example
if( (_access( "test.txt", 0 )) == -1 )
{
    printf( "test.txt is not exists.\n" );
}

还可以使用另一个api:

//函数定义
int _stat(
   const char *path, //path 指向字符串的指针,该字符串包含现有文件或目录的路径。
   struct _stat *buffer //buffer 指向存储结果的结构的指针。
);
//example
struct _stat fileStat;
if(_stat(path, &fileStat) == -1)
{
   printf( "file is not exists.\n" );
}

_stat如果获取到文件状态信息,将返回 0。 返回值 – 1 表示错误,在这种情况下 errno 设置为 ENOENT,表示找不到该文件名或路径。 返回值为 EINVAL 表示参数无效;这种情况下 errno 还会设置为 EINVAL。(来自msdn)

事实上 fopen系列 或者_stat 系列函数都不能准确判断文件是否存在,因为
fopen:文件的权限与fopen的参数不一致,可能返回EACCESS,
stat : 目录的某一级不允许搜索会返回EACCESS
还有一些其他的错误
总的来说,要判断文件是否存在,stat的情况要简单的多,比用open要好

【ps】 其实这并没有解决我的问题,在多进程访问文件的时候,使用fopen_s打开文件有时会返回失败(permision deny),而使用_fsopen会返回broken pipe,并且每次出错的文件都不是同一个。应该不是加锁的问题,因为不会有两个进程同时访问同一文件。最后尝试用C++的fstream打开文件,仍然会出现问题,慢慢查~

参考:
msdn: https://msdn.microsoft.com/zh-cn/library/1w06ktdy.aspx.
msnd: https://msdn.microsoft.com/zh-cn/library/14h5k7ff.aspx