問題の解決策をオンラインで見つけることができません。
Unixで関数を呼び出し、ディレクトリのパスを渡し、存在するかどうかを知りたいです。 opendir()
は、ディレクトリが存在しない場合はエラーを返しますが、私の目標は、実際に開いてエラーを確認し、エラーがなければ閉じて、ファイルがディレクトリかどうかを確認することです。
それを行う便利な方法はありますか?
POSIXシステムには、2つの関連する関数があります: stat()およびlstat() 。これらは、パス名が実際にアクセスする権限を持っているオブジェクトを参照しているかどうかを調べるために使用されます。参照している場合、返されるデータはオブジェクトのタイプを示します。 stat()
とlstat()
の違いは、指定した名前がシンボリックリンクである場合、stat()
はシンボリックリンク(または、チェーンでつながれている場合はリンク)に従うことです。 lstat()
はシンボリックリンク自体について報告しますが、リンクチェーンの最後にあるオブジェクトについて報告します。
#include <sys/stat.h>
struct stat sb;
if (stat(pathname, &sb) == 0 && S_ISDIR(sb.st_mode))
{
...it is a directory...
}
関数が成功したことを示している場合、 <sys/stat.h>
のS_ISDIR()マクロを使用して、ファイルが実際にディレクトリであるかどうかを判断します。
他のS_IS*
マクロを使用して、他のファイルタイプを確認することもできます。
S_ISDIR
—ディレクトリS_ISREG
—通常のファイルS_ISCHR
—キャラクターデバイスS_ISBLK
—ブロックデバイスS_ISFIFO
— FIFOS_ISLNK
—シンボリックリンクS_ISSOCK
—ソケット(他のいくつかのファイルタイプも提供するシステムもあります。たとえば、S_ISDOOR
はSolarisで利用可能です。)
test -d
を使用できます
別の簡単な方法は次のとおりです。
int check(unsigned const char type) {
if(type == DT_REG)
return 1;
if(type == DT_DIR)
return 0;
return -1;
}
次に、struct dirent *オブジェクトのd_typeをcheck関数に渡すことができます。
Checkが1を返す場合、そのパスは通常のファイルを指します。
Checkが0を返す場合、そのパスはディレクトリを指します。
それ以外の場合は、ファイルでもディレクトリでもありません(ブロックデバイス/シンボリックリンクなどが可能です)。
テスト済みで正常に動作しています:
int file_exist (char *filename)
{
char s[200];
sprintf(s, "test -e %s", filename);
if (system(s) == 0){
return 1;
}else{
return 0;
}
}
このファイルシステムオブジェクトのタイプをあまり気にしない場合、access(name、F_OK)はこの名前を持つ何かの存在をチェックします。これがディレクトリであることを確認する必要がある場合は、stat()を使用し、S_ISDIR()マクロでタイプをチェックします。
関数statはあなたが望むことをするかもしれないと思います(ディレクトリのテストはしていません)。 C++では、boost :: filesystemライブラリも使用できます。