我正在使用的方式只是尝试fopen()要检查的文件,
/* --- does file exist??? --- */
char fname[999] = "whatever"; /* constructed during execution */
FILE *fp = NULL; /* try to fopen(fname,"r") */
int isfilefound = 0; /* set true if fopen() succeeds */
if ( (fp = fopen(fname,"r")) /* try to fopen() for read */
!= NULL ) { /* succeeded */
isfilefound = 1; /* set file found flag */
fclose(fp); } /* and just close the file */
是否有更快,更少资源的方式?... unix / linux的特定方式?一种Windows方式?并且最好是便携式posix兼容方式(如上所述)?它已经完成了很多次(1000次),因此我不希望无缘无故地打开和关闭文件。
-------------------------------------------- ---------------------
编辑好的,根据下面的答案,我整理了以下小功能,旨在检查文件(已经:)是否存在于posix,windows,其他便携式方式......
/* ==========================================================================
* Function: isfilexists ( path )
* Purpose: check whether file at path exists
* --------------------------------------------------------------------------
* Arguments: path (I) pointer to null-terminated char string
* containing "path/filename.ext" of
* file whose existence is to be determined
* (path is relative to pwd unless explicitly
* absolute by initial '/' or other syntax)
* --------------------------------------------------------------------------
* Returns: ( int ) 1 if file at path exists, or 0 if not
* --------------------------------------------------------------------------
* Notes: o conditional compiles for various systems,
* depending on whether POSIX or WINDOWS is #define'ed...
* o ...method used:
* 1: use access() on Posix systems,
* 2: PathFileExists() on Windows systems,
* 3: fopen() on any other systems.
* ======================================================================= */
/* --- entry point --- */
int isfilexists ( char *path )
{
/* ---
* allocations and declarations
* ------------------------------- */
int isexists = 0; /* set true if file at path exists */
FILE *fp = NULL; /* fopen() for non-posix,windows */
#define POSIX /* just for testing */
/* ---
* determine whether file at path already exists
* ------------------------------------------------ */
#if defined(POSIX) /* posix-compliant system... */
#include <unistd.h>
if ( access(path,F_OK) == 0 ) /* file at path exists */
isexists = 1; /* so set file exists flag */
#else
#if defined(WINDOWS) /* Windows system... */
isexists = PathFileExists(path); /* set flag if file at path exists */
#else
/* --- fopen() for any other non-posix, non-windows system --- */
if ( (fp = fopen(path,"r")) /* try to fopen() for read */
!= NULL ) { /* succeeded */
isexists = 1; /* set file exists flag */
fclose(fp); } /* and just close the file */
#endif
#endif
return ( isexists ); /* back to caller with 1 if file at path exists */
} /* --- end-of-function isfilexists() --- */
访问()和fopen()方法测试并正常工作。无法测试Windows的PathFileExists()。我仍然想弄清楚#define'ed符号是什么,以便自动且明确地检查条件编译。
答案 0 :(得分:5)
你正在以错误的方式思考这个问题。你不应该“检查一个文件是否已经存在”,因为它有一个固有的TOCTOU race - 在你检查文件是否存在的时间和你对该信息采取行动的时间之间,可能会出现另一个过程并更改文件是否存在,使检查无效。
取而代之的取决于你想知道的原因。一个非常常见的情况是,您只想创建文件(如果该文件尚不存在),在这种情况下,您在open
模式下使用较低级别的O_EXCL
函数:
int fd = open("whatever", O_WRONLY|O_CREAT|O_EXCL, 0666);
if (fd == -1 && errno == EEXIST) {
/* the file already exists */
} else if (fd == -1) {
/* report that some other error happened */
} else {
FILE *fp = fdopen(fd, "w");
/* write data to fp here */
}
另一个非常常见的情况是,如果文件不存在,您要创建文件,或者如果文件将新数据附加到文件中;可以使用"a"
模式将fopen
或O_APPEND
标记为open
来完成此操作。
答案 1 :(得分:4)
在Windows上,有PathFileExists()。
也就是说,如果你检查文件的存在是因为你的代码需要文件,这是错误的方法 - 文件系统不在你的程序控制之内,所以这将是一个竞争条件,只有正确的方法才能在打开文件时正确处理错误。