MW211 EXIT

devlog
C言語/scandir()の使い方
2013年05月06日
「scandir()」を使うと、指定したディレクトリ配下のファイル一覧情報を取得できる。
しかも、抽出や並び替えも同時に行うことができる。
いってみれば、「opendir()、readdir()、closedir()、qsort()」を
まとめてやってくれる便利か関数だ。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
【scandir()を使用する例】
┌──────────────────────────────────────┐
│    struct dirent  **dirEnt;  // エントリ情報                               │
│    int  count = scandir(ディレクトリパス,  // ディレクトリを指定する       │
│                         &dirEnt,           // エントリ情報を取得する       │
│                         scanExtract,       // 抽出条件関数                 │
│                         scanSort);         // ソート条件関数               │
│    if (count < 0) {  // エラーの場合は件数が-1となる                       │
│        エラー処理;                                                         │
│    }                                                                       │
│    for (int i = 0; i < count; ++i) {                                       │
│        ここで「dirEnt[i]->d_name」を参照すればファイル名が取得できる;      │
│        free(dirEnt[i]);  // 個別に領域解放せねばならない                   │
│    }                                                                       │
│    free(dirEnt);  // 最後に全体を領域解放せねばならない                    │
└──────────────────────────────────────┘
「scandir()」の第二引数にて、「struct dirent」型のポインタに
エントリ情報(ファイル一覧)が取得される。
取得した件数は戻り値で取得できる(「-1」の場合はエラー)
あとはその一覧を参照するだけでよい。
ただし、「scandir()」内にて「malloc()」で領域を確保しているようなので
「free()」で解放しなければならない。
これは、ファイル一覧一件一件ごととそれらを統括する全体について
それぞれ行わなければならないようだ。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
【抽出条件関数の例】(「.」「..」を除外する)
┌──────────────────────────────────────┐
│int  scanExtract(const struct dirent*  dir)                                 │
│{                                                                           │
│    return (dir->d_name[0] != '.');                                         │
│}                                                                           │
└──────────────────────────────────────┘
「scandir()」の第三引数にて、関数を指定することで抽出条件を指定できる。
関数は別途自分で定義しなければならない。(関数名は任意)
戻り値が「0」の場合は除外されることになる。
#上記の例でいえば、先頭が「.」から始まるファイル名は
  戻り値「false(=0)」となり除外される(それ以外は戻り値「true(=1)」)
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
【ソート条件関数の例】(ファイル名で昇順・降順にを並び替える)
┌──────────────────────────────────────┐
│int  scanSort(const void*  s1,                                              │
│              const void*  s2)                                              │
│{                                                                           │
│    if (昇順の場合) {                                                       │
│        return strcmp((*(struct dirent **)s1)->d_name,                      │
│                      (*(struct dirent **)s2)->d_name);                     │
│    } else {                                                                │
│        return strcmp((*(struct dirent **)s2)->d_name,                      │
│                      (*(struct dirent **)s1)->d_name);                     │
│    }                                                                       │
│}                                                                           │
└──────────────────────────────────────┘
「scandir()」の第四引数にて、関数を指定することでソート条件を指定できる。
関数は別途自分で定義しなければならない(関数名は任意)。
但し、ファイル名昇順のソートであれば「alphasort()」が
バージョン名昇順のソートであれば「versionsort()」という関数が用意されている。
#上記の場合は、ファイル名降順もサポートしたいので
  自前でファイル名のソートを実装した場合の例である
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
分類:C/C++