最近はデータを大量に取得して、一気にバッチ処理に掛けるみたいなことをやってますが、いい加減シェルスクリプトを書くのがめんどくさくなってきたので、それ専用のクラスを作ってしまおうと昨日くらいから書き始めました。で、一応できたんでソースを載せてみます。こうした方がいいよ、という意見があれば是非コメントまで。
#include <sys/types.h> #include <dirent.h> #include <iostream> using std::cerr; using std::endl; void show_files( const char* _cur, const char* _parent) { std::string path(_parent); if ( path.length() > 0 ) path += "/"; path += _cur; DIR* dp = opendir( path.c_str() ); if ( dp == NULL ) { cerr << path << endl; return; } struct dirent* entp; while ( (entp = readdir(dp)) != NULL ) { std::string buff = path; if ( entp->d_name[0] != '.' ) // ドットで始まるディレクトリを回避 dir_files( entp->d_name, buff.c_str() ); } closedir(dp); return; }
本当は sys/stat.h 内のstat()を使って
#include <sys/stat.h> int is_dir (const struct dirent* _entp) { struct stat sb; stat(_entp->d_name, &sb); if ( S_ISDIR(sb.st_mode) ) return 1; else if ( S_ISREG(sb.st_mode) ) return 2; else return 0; }
みたいな感じにしたかったんだけど、どうもカレントディレクトリ以外のディレクトリのファイルのモードはS_IFSOCKになってしまうみたいですね。そのおかげでだいぶはまってしまいました。コレを解消する方法はないかなぁ?
ちなみにcygwinとLinuxやBSDでdirent構造体の実装が違うみたいですね。dirent.d_type を使えば一発でディレクトリかどうかの判別ができたのに。
ここではd_typeは
とあるんで、「cygwinもあるんじゃね?」と期待したけど、実際のcygwinの実装では
struct dirent { long d_version; long d_reserved[2]; long d_fd; ino_t d_ino; char d_name[256]; };
となってました。見事にありません。残念。