単にファイルを開こうとするよりも良い方法はありますか?
int exists(const char *fname)
{
FILE *file;
if ((file = fopen(fname, "r")))
{
fclose(file);
return 1;
}
return 0;
}
unistd.h
にあるaccess()
関数を検索します。関数を次のように置き換えることができます
if( access( fname, F_OK ) != -1 ) {
// file exists
} else {
// file doesn't exist
}
また、R_OK
の代わりにW_OK
、X_OK
、およびF_OK
を使用して、存在ではなく読み取り許可、書き込み許可、および実行許可をそれぞれ確認できます。それらのいずれかをOR一緒に使用できます(つまり、R_OK|W_OK
を使用して読み取りおよび書き込み許可の両方を確認します)
更新:Windowsでは、W_OK
を使用して書き込み権限を確実にテストすることはできません。アクセス機能ではDACLが考慮されないためです。ファイルには読み取り専用属性が設定されていないため、access( fname, W_OK )
は0(成功)を返しますが、ファイルへの書き込み許可がない場合があります。
次のようにstatを使ってください。
int file_exist (char *filename)
{
struct stat buffer;
return (stat (filename, &buffer) == 0);
}
そしてこれを次のように呼ぶ:
if (file_exist ("myfile.txt"))
{
printf ("It exists\n");
}
通常、ファイルが存在するかどうかを確認したいのは、存在しない場合はそのファイルを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 */
}
はい。 stat()を使用してください。 link を参照してください。
ファイルが存在しない場合、Statは失敗します。それ以外の場合は成功します。それが存在していても、それが存在するディレクトリへの読み取りアクセス権がない場合は、それも失敗します。その場合、どの方法でも失敗します(アクセス権に従って、ディレクトリの内容を調べる方法は?簡単に言うと、できません。
ああ、他の人が言ったように、あなたもaccess()を使うことができます。ただし、ファイルが存在するかのようにstat()を使用すると、すぐに多くの有用な情報が得られます(最終更新日、ファイルの所有者やグループ、アクセス権など)。 。
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
}
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() は行くべきより良い方法のように見えますか。ほら、.
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
Realpath()関数を使うことができます。
resolved_file = realpath(file_path, NULL);
if (!resolved_keyfile) {
/*File dosn't exists*/
perror(keyfile);
return -1;
}