Mono.Unix.Native.Syscall.readdir_r 最終更新日 2008年1月26日 9:08 Mono.Unix.Native.Syscall.readdir_rを使ってディレクトリを再帰的に走査する。 別ウィンドウで開く すべて選択してコピー ダウンロード 行番号を表示する // gmcs DirectoryEnumeration.cs /r:Mono.Posix.dll // mono DirectoryEnumeration.exe ./ using System; using Mono.Unix.Native; public class DirectoryEnumeration { private enum DirentType : byte { DT_UNKNOWN = 0, DT_FIFO = 1, DT_CHR = 2, DT_DIR = 4, DT_BLK = 6, DT_REG = 8, DT_LNK = 10, DT_SOCK = 12, DT_WHT = 14 }; static void Main(string[] args) { Enumerate(args[0], 0); } private static void Enumerate(string dir, int depth) { IntPtr dirp = IntPtr.Zero; string indent = new string(' ', depth); try { dirp = Syscall.opendir(dir); // ディレクトリを開けなかった場合 if (IntPtr.Zero.Equals(dirp)) return; for (; ; ) { IntPtr result; Dirent dirent = new Dirent(); if (0 != Syscall.readdir_r(dirp, dirent, out result)) break; // すべてのエントリを読んだ場合 if (IntPtr.Zero.Equals(result)) break; // 削除されたエントリだった場合 if (0 == dirent.d_ino) continue; // エントリの種類を調べる switch((DirentType)dirent.d_type) { case DirentType.DT_DIR: // ディレクトリ Console.WriteLine("{0}{1}/", indent, dirent.d_name); if ("." == dirent.d_name) { // 自分自身 } else if (".." == dirent.d_name) { // 親ディレクトリ } else { string subdir = dir; if (!subdir.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString())) subdir += System.IO.Path.DirectorySeparatorChar; subdir += dirent.d_name; // 子ディレクトリを再帰的に走査する Enumerate(subdir, depth + 1); } break; case DirentType.DT_REG: // 普通のファイル Console.WriteLine("{0}{1}", indent, dirent.d_name); break; default: // それ以外(シンボリックリンク、ブロックデバイス、ソケット等) Console.WriteLine("{0}{1}", indent, dirent.d_name); break; } } } finally { if (!IntPtr.Zero.Equals(dirp)) { Syscall.closedir(dirp); } } } }