2012-04-29 4 views
3

ファイルがディレクトリ、リンク、または通常のファイルであるかどうかを確認します。私はディレクトリをループし、各ファイルをstruct dirent *として保存します。私はd_inoS_ISDIR(m)S_ISLINK(m)、またはS_ISREG(m)に渡そうとしますが、ファイルにかかわらず、私は肯定的な結果を得ません。だから私の質問は:struct direntS_ISDIR(m)をどうすればいいですか?sys/stat S_ISDIR(m)with struct dirent

答えて

7

あなたがreaddir(3)を使用してディレクトリを読んだとき、ファイルの種類は、あなたが受け取る各struct direntd_typeメンバ変数ではなく、d_inoメンバーに保存されています。あなたはめったにinode番号を気にしません。

ただし、すべての実装がd_typeメンバーのために有効なデータを持っていますので、あなたは(そのファイルの種類を決定するために、各ファイルにstat(3)lstat(3)を呼び出すあなたはシンボリックリンクに興味があるならlstatを使用するか、またはstatを使用する必要がありますシンボリックリンクのターゲットに興味がある場合)、S_IS***マクロを使用してst_modeメンバーを調べてください。

一般的なディレクトリの反復は次のようになります。上記のように

// Error checking omitted for expository purposes 
DIR *dir = opendir(dir_to_read); 
struct dirent *entry; 

while((entry = readdir(dir)) != NULL) 
{ 
    struct stat st; 
    char filename[512]; 
    snprintf(filename, sizeof(filename), "%s/%s", dir_to_read, entry->d_name); 
    lstat(filename, &st); 

    if(S_ISDIR(st.st_mode)) 
    { 
     // This directory entry is another directory 
    } 
    else if(S_ISLINK(st.st_mode)) 
    { 
     // This entry is a symbolic link 
    } 
    else if(S_ISREG(st.st_mode)) 
    { 
     // This entry is a regular file 
    } 
    // etc. 
} 

closedir(dir); 
+1

'S_IS *'マクロはd_typeで直接使用することはできません。私が見たほとんどのシステムでは、それらはお互いから12ビット分オフセットされています。 'IFTODT'マクロと' DTTOIF'マクロを使用しなければなりません(標準ではありません、あるいは 'DT_ *'マクロ値と直接比較するだけです) –

+0

@R ..:おっとありがとう、良い点 –

+0

"d_type"フィールドはありませんSolaris上で;-) – Igor

0

に対してはS_ISDIR(m)、S_ISLINK(m)を使用し、struct direntでは使用しません。例えば:

struct stat sb; 
... 
stat ("/", &sb); 
printf ("%d", S_ISDIR (sb.st_mode)); 
0

残念ながら、あなたは、構造体はdirentメンバーとS_IS *マクロを使用することはできません。しかし、メンバーd_typeにはすでにあなたのための情報があるので、必要はありません。あなたは直接このようにそれをテストすることができます。

struct dirent someDirEnt; 
... //stuff get it filled out 
if(someDirEnt.d_type==DT_LNK) 
...//whatever you link 

は特にd_typeメンバーが含まれる場合があります。

DT_BLK  This is a block device. 
    DT_CHR  This is a character device. 
    DT_DIR  This is a directory. 
    DT_FIFO  This is a named pipe (FIFO). 
    DT_LNK  This is a symbolic link. 
    DT_REG  This is a regular file. 
    DT_SOCK  This is a UNIX domain socket. 
    DT_UNKNOWN The file type is unknown.