515

単にファイルを開こうとするよりも良い方法はありますか?

int exists(const char *fname)
{
    FILE *file;
    if ((file = fopen(fname, "r")))
    {
        fclose(file);
        return 1;
    }
    return 0;
}
4

8 に答える 8

707

にあるaccess()関数を検索しunistd.hます。関数を次のように置き換えることができます

if( access( fname, F_OK ) == 0 ) {
    // file exists
} else {
    // file doesn't exist
}

R_OKW_OK、およびX_OKの代わりにF_OK、存在ではなく、読み取り許可、書き込み許可、および実行許可を (それぞれ) チェックすることもできます。また、それらのいずれかを一緒に OR することもできます (つまり、を使用して読み取り書き込みの両方の許可をチェックしますR_OK|W_OK) 。

更新W_OK: Windows では、アクセス関数が DACL を考慮しないため、書き込み許可を確実にテストするために使用できないことに注意してください。access( fname, W_OK )ファイルに読み取り専用属性が設定されていないため、0 (成功) が返されることがありますが、それでもファイルへの書き込み権限がない可能性があります。

于 2008-10-23T14:59:32.250 に答える
130

stat次のように使用します。

#include <sys/stat.h>   // stat
#include <stdbool.h>    // bool type

bool file_exists (char *filename) {
  struct stat   buffer;   
  return (stat (filename, &buffer) == 0);
}

次のように呼び出します。

#include <stdio.h>      // printf

int main(int ac, char **av) {
    if (ac != 2)
        return 1;

    if (file_exists(av[1]))
        printf("%s exists\n", av[1]);
    else
        printf("%s does not exist\n", av[1]);

    return 0;
}
于 2008-10-23T15:00:53.727 に答える
96

通常、ファイルが存在するかどうかを確認する場合、存在しない場合はそのファイル を作成する必要があるためです。Graeme Perrowの答えは、そのファイルを作成したくない場合は適切ですが、作成すると競合状態に対して脆弱になります。ファイルが存在するかどうかを確認する間に別のプロセスがファイルを作成し、実際に開いてファイルに書き込む可能性があります。 。(笑わないでください...作成されたファイルがシンボリックリンクである場合、これはセキュリティに悪影響を与える可能性があります!)

存在を確認し、存在しない場合はファイル作成して、競合状態が発生しないようにアトミックに作成する場合は、次を使用します。

#include <fcntl.h>
#include <errno.h>

fd = open(pathname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
if (fd < 0) {
  /* failure */
  if (errno == EEXIST) {
    /* the file already existed */
    ...
  }
} else {
  /* now you can use the file */
}
于 2008-10-23T17:14:05.050 に答える
34

はい。を使用しstat()ます。のマニュアル ページを参照してくださいstat(2)

stat()ファイルが存在しない場合は失敗し、そうでない場合は成功する可能性が高くなります。存在するが、それが存在するディレクトリへの読み取りアクセス権がない場合、それも失敗しますが、その場合、どのメソッドも失敗します (アクセス権に従って表示されない可能性があるディレクトリの内容をどのように検査できますか?単に、できません)。

ああ、他の誰かが言ったように、 も使用できますaccess()。ただしstat()、ファイルが存在するかのように、多くの有用な情報がすぐに得られるので、私は .

于 2008-10-23T14:59:16.070 に答える
19
FILE *file;
    if((file = fopen("sample.txt","r"))!=NULL)
        {
            // file exists
            fclose(file);
        }
    else
        {
            //File not found, no memory leak since 'file' == NULL
            //fclose(file) would cause an error
        }
于 2015-04-08T09:08:01.523 に答える
6

Visual C ++のヘルプから、私は

/* ACCESS.C: This example uses _access to check the
 * file named "ACCESS.C" to see if it exists and if
 * writing is allowed.
 */

#include  <io.h>
#include  <stdio.h>
#include  <stdlib.h>

void main( void )
{
   /* Check for existence */
   if( (_access( "ACCESS.C", 0 )) != -1 )
   {
      printf( "File ACCESS.C exists\n" );
      /* Check for write permission */
      if( (_access( "ACCESS.C", 2 )) != -1 )
         printf( "File ACCESS.C has write permission\n" );
   }
}

また、次のモード値にも注目する価値があります。_access(const char *path,int mode)

  • 00:存在のみ

  • 02:書き込み許可

  • 04:読み取り許可

  • 06:読み取りおよび書き込み許可

fopenファイルは存在するが、要求どおりに開くことができない状況では失敗する可能性があるためです。

編集:Meckiの投稿を読んでください。 stat()きちんとした方法のように見えます。ほんとうに。

于 2008-10-23T15:07:01.343 に答える