web-dev-qa-db-ja.com

ファイルがCに存在するかどうかを確認するための最良の方法は何ですか?

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

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

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

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

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

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

528
Graeme Perrow

次のようにstatを使ってください。

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

そしてこれを次のように呼ぶ:

if (file_exist ("myfile.txt"))
{
  printf ("It exists\n");
}
102
codebunny

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

存在を確認したい場合およびファイルが存在しない場合は作成しますatomically条件、そしてこれを使用してください:

#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 */
}
75
Dan Lenski

はい。 stat()を使用してください。 link を参照してください。

ファイルが存在しない場合、Statは失敗します。それ以外の場合は成功します。それが存在していても、それが存在するディレクトリへの読み取りアクセス権がない場合は、それも失敗します。その場合、どの方法でも失敗します(アクセス権に従って、ディレクトリの内容を調べる方法は?簡単に言うと、できません。

ああ、他の人が言ったように、あなたもaccess()を使うことができます。ただし、ファイルが存在するかのようにstat()を使用すると、すぐに多くの有用な情報が得られます(最終更新日、ファイルの所有者やグループ、アクセス権など)。 。

28
Mecki
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
        }
8
mesutpiskin

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" );
   }
}

_accesssのモード値(const char * path、 int mode )にも注目してください。

00存在のみ

02書き込み許可

04読み取り許可

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

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

編集:ただMeckiの投稿を読んでください。 stat() は行くべきより良い方法のように見えますか。ほら、.

5
SmacL

unistd.hにある access() functionはLinuxには良い選択だと思います( stat も使えます)。

あなたはこのようにそれを使うことができます:

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

void fileCheck(const char *fileName);

int main (void) {
    char *fileName = "/etc/sudoers";

    fileCheck(fileName);
    return 0;
}

void fileCheck(const char *fileName){

    if(!access(fileName, F_OK )){
        printf("The File %s\t was Found\n",fileName);
    }else{
        printf("The File %s\t not Found\n",fileName);
    }

    if(!access(fileName, R_OK )){
        printf("The File %s\t can be read\n",fileName);
    }else{
        printf("The File %s\t cannot be read\n",fileName);
    }

    if(!access( fileName, W_OK )){
        printf("The File %s\t it can be Edited\n",fileName);
    }else{
        printf("The File %s\t it cannot be Edited\n",fileName);
    }

    if(!access( fileName, X_OK )){
        printf("The File %s\t is an Executable\n",fileName);
    }else{
        printf("The File %s\t is not an Executable\n",fileName);
    }
}

そして、あなたは次のような出力を得ます。

The File /etc/sudoers    was Found
The File /etc/sudoers    cannot be read
The File /etc/sudoers    it cannot be Edited
The File /etc/sudoers    is not an Executable
3
Michi

Realpath()関数を使うことができます。

resolved_file = realpath(file_path, NULL);
if (!resolved_keyfile) {
   /*File dosn't exists*/
   perror(keyfile);
   return -1;
}
3
bharath reddy