التحقق مما إذا كانت المجلدات الفرعية موجودة Linux
سؤال
أحاول التحقق مما إذا كان لدى المجلد أي مجلدات دون التكرار من خلال أطفاله ، في Linux. الأقرب الذي وجدته حتى الآن يستخدم ftw
والتوقف في المجلد الفرعي الأول - أو باستخدام scandir
والتصفية من خلال النتائج. كلاهما ، مع ذلك ، مبالغة لأغاني ، أريد ببساطة نعم/لا.
على Windows ، يتم ذلك عن طريق الاتصال SHGetFileInfo
ثم الاختبار dwAttributes & SFGAO_HASSUBFOLDER
على الهيكل الذي تم إرجاعه. هل هناك مثل هذا الخيار على Linux؟
المحلول
الجواب القياسي هو الاتصال Stat في الدليل ، ثم تحقق من حقل ST_NLINK ("عدد الروابط الصلبة"). على نظام الملفات القياسي ، يضمن كل دليل أن يكون له رابطان صلبان (.
ويشير الرابط من الدليل الأم إلى الدليل الحالي) ، لذلك يشير كل رابط صلب يتجاوز 2 إلى دليل فرعي (على وجه التحديد ، الدليل الفرعي ..
رابط إلى الدليل الحالي).
ومع ذلك ، أفهم أن أنظمة الملفات ليست مطلوبة لتنفيذ هذا (انظر ، على سبيل المثال ، نشر القائمة البريدية هذه) ، لذلك ليس مضمون العمل.
خلاف ذلك ، عليك أن تفعل كما تفعل:
- تكرار على محتويات الدليل باستخدام العالم مع GNU محددة
GLOB_ONLYDIR
العلم ، أو الفراغ, ، أو Readdir. - مكالمة Stat في كل نتيجة وتحقق
S_ISDIR(s.st_mode)
للتحقق من أن الملفات الموجودة هي الدلائل. أو ، بشكل غير محدد ، تحققstruct dirent.d_type
: إذا كان الأمر كذلكDT_DIR
ثم إنه ملف ، وإذا كان كذلكDT_UNKNOWN
, ، سيكون عليك أن تقتصرها بعد كل شيء.
نصائح أخرى
يبدو لي الإمكانيات التي ذكرتها (وكذلك E.James) وكأنها أكثر ملاءمة لنص shell من برنامج C ++. على افتراض أن علامة "C ++" كانت متعمدة ، أعتقد أنك ربما تكون أفضل حالًا باستخدام واجهة برمجة تطبيقات POSIX مباشرة:
// warning: untested code.
bool has_subdir(char const *dir) {
std::string dot("."), dotdot("..");
bool found_subdir = false;
DIR *directory;
if (NULL == (directory = opendir(dir)))
return false;
struct dirent *entry;
while (!found_subdir && ((entry = readdir(directory)) != NULL)) {
if (entry->d_name != dot && entry->d_name != dotdot) {
struct stat status;
stat(entry->d_name, &status);
found_subdir = S_ISDIR(status.st_mode);
}
}
closedir(directory);
return found_subdir;
}
يفعل getDirentries هل تريد أن تفعل ذلك؟ أعتقد أنه لا شيء لا شيء إذا لم تكن هناك أدلة. كنت قد جربت هذا بنفسي ولكني مؤقتًا دون الوصول إلى مربع Linux :(