見出し画像

続C言語教室 - 第19回 ファイル操作(3) ディレクトリの読み方

ファイルにアクセスするのにそのファイル名を指定して開くのは当たり前といえば当たり前なのですが、いったいどんなファイルがあるのかを調べたいことも出てきます。ファイル名をはじめファイルに関する情報は階層化されたディレクトリにあります。ということで、ディレクトリにある情報をプログラムで調べて使うにはどうすれば良いのかという話です。

ディレクトリは詰まる所、特殊ではありますがファイルの一種なので、ディレクトリを開いて読み出し、そして最後に閉じて使います。ディレクトリの書き込み権限があったとしても、ディレクトリへの書き込みは出来ません。

これらのライブラリ関数はC言語の標準ライブラリという訳ではなく、OSやファイルシステムによって差異があるのですが POSIX の枠組みで互換性が図られています。

DIR * opendir(const char *filename);

ディレクトリを開く

struct dirent * readdir(DIR * dirp);

ディレクトリ要素を読み出す

※この関数を呼び出すたびに読み出し位置が次の要素へ移る。残りがなくなればNULLを返す。

void closedir(struct dirent *dir);

ディレクトリを閉じる

これらの関数を呼び出す際には以下のファイルのインクルードが必要です。

#include <sys/types.h>
#include <dirent.h>

sys/types.h はいらないケースもあるかも

readdir() で得られた要素へのポインタを使って、ファイル名(d_name)などを取得することが出来ます。それぞれのファイルの情報については得られたファイル名を使って stat() で詳細な情報を得ます。構造体の中身は以下のリンクにあります。

manページ — DIR

manページ — STAT

ここでファイルがディレクトリであることがわかれば再帰的にディレクトリを開いて調べていくことも出来ます。

C言語を駆使したディレクトリ操作の全て!Dirent関数の10つの使い方と応用例

opendir() — ディレクトリーのオープン

いずれにしても、ディレクトリの具体的な構造はOSによってもファイルシステム次第です。それぞれのフィールドの意味がどうなっているかは相手次第の部分もあります。特にWindowsに関しては、これらの関数が用意されていないこともあり、基本的には FindFirstFile(), FindNextFile(), FindClose() という関数を使ってくれとなっています(OS X は POSIX で行けるようだ)。

ディレクトリ内のファイルの一覧表示

そんなに難しい処理ではないので、頑張って互換性のある関数を書いてしまった方もいるようです。

opendir・readdir・closedirをエミュレートする

dirent.h - dirent API for Microsoft Visual Studio

https://svn.apache.org/repos/asf/avro/trunk/lang/c/tests/msdirent.h

これらの情報を使ってディレクトリにある特定の種類のファイルや、特定の名前のファイルの一覧を手に入れることができるので、その一覧を使って、それぞれのファイルに対する処理を書いていくことが出来るようになるわけです。* や ? などのワイルドカードの展開はシェルが行ってくれているので、ファイル名のパターンで処理を書くには、得られた一覧から正規表現へのマッチングを自力で行う必要があります。

ところでファイルの中には一般のファイルやディレクトリ以外のファイルもあります。その辺りの話は次回ということで。

ヘッダ画像は、AIにこの記事の文章を食べさせて生成しました。

#プログラミング #C言語 #プログラミング講座 #C言語教室 #ファイルシステム #ディレクトリ #opendir #readdir #closedir #stat

いいなと思ったら応援しよう!

kzn
頂いたチップは記事を書くための資料を揃えるために使わせていただきます!