برای ایجاد دایرکتوریهای جدید در سیستم فایل، کتابخانه std::filesystem دو تابع اصلی ارائه میدهد که تفاوت مهمی در نحوهی عملکرد آنها وجود دارد. تابع create_directory یک دایرکتوری جدید در مسیر مشخص شده ایجاد میکند، اما شرط مهم آن این است که دایرکتوری والد (Parent Directory) از پیش وجود داشته باشد و در صورت عدم وجود، عملیات با خطا مواجه میشود . در مقابل، تابع create_directories (با فرم جمع) بسیار منعطفتر عمل کرده و تمام دایرکتوریهای مسیر مشخصشده را که هنوز وجود ندارند، بهصورت یکجا و بهصورت بازگشتی ایجاد میکند؛ بهگونهای که اگر "a/b/c" را به آن بدهید، دایرکتوریهای a، b و c
را بهترتیب میسازد . یک نکتهی ظریف در استفاده از این توابع این است که
اگر مسیر مورد نظر از قبل بهعنوان یک دایرکتوری معتبر وجود داشته باشد،
تابع هیچ خطایی گزارش نمیدهد و صرفاً مقدار false را بازمیگرداند که این رفتار، امکان استفادهی ایمن از آنها را در سناریوهای مختلف فراهم میکند .
تکنیک کپی کردن ویژگیها
برای ایجاد یک دایرکتوری جدید با ویژگیهای مشابه یک دایرکتوری از پیش موجود، نسخهی دومی از تابع create_directory وجود دارد که یک مسیر existing_p
را بهعنوان مرجع دریافت میکند . این تابع بسیار کاربردی است، بهویژه
زمانی که نیاز به حفظ مجوزهای دسترسی (Permissions) یکسان در یک ساختار
دایرکتوری جدید داریم. در سیستمهای مبتنی بر POSIX (مانند لینوکس و مک)،
ویژگیهایی مانند مجوزها از مسیر مرجع کپی میشوند، اما در سیستمعامل
ویندوز، ویژگیها کپی نمیشوند و این تفاوت به ماهیت سیستمعامل مربوط است .
همچنین توجه به این نکته مهم است که این نسخه از تابع، بهصورت خودکار
توسط copy هنگام کپی بازگشتی دایرکتوریها فراخوانی میشود .
پیمایش با directory_iterator
کلاس directory_iterator یک تکرارگر (Iterator) استاندارد برای پیمایش محتویات یک دایرکتوری (بدون ورود به زیردایرکتوریها) است . این کلاس از حلقههای مبتنی بر محدوده (Range-based for loops) پشتیبانی کامل میکند که نوشتن کدهای پیمایش را بهشدت ساده میسازد. مهمترین نکته در مورد این تکرارگر، نوع مقدار (Value Type) آن است که directory_entry نام دارد و شامل اطلاعات کاملی دربارهی هر ورودی دایرکتوری است . همچنین این تکرارگر بهگونهای هوشمند طراحی شده که ورودیهای ویژهی . و .. را نادیده میگیرد و تنها روی ورودیهای واقعی تمرکز میکند . یک نکتهی بسیار کاربردی در مورد directory_iterator
این است که بسیاری از پیادهسازیهای سیستمعامل، هنگام بازگشت هر ورودی،
ویژگیهای آن را نیز دریافت میکنند (مانند نوع فایل یا اندازه) و این کلاس
از این قابلیت برای ذخیرهسازی این اطلاعات در directory_entry استفاده میکند، بهطوری که در حین پیمایش، نیازی به فراخوانی سیستمهای اضافی برای دریافت ویژگیهای فایل نیست و این امر باعث افزایش چشمگیر سرعت کار میشود .
پیمایش بازگشتی با recursive_directory_iterator
اگر نیاز به پیمایش تمام محتویات یک دایرکتوری بههمراه تمام زیرشاخههای آن دارید، recursive_directory_iterator
ابزار مناسب شماست . این تکرارگر نیز از حلقههای مبتنی بر محدوده
پشتیبانی کرده و تمام ورودیهای سلسلهمراتب را یکبار بازدید میکند . یکی
از قابلیتهای جالب آن، متد depth() است که عمق جاری
را در ساختار دایرکتوری بازمیگرداند؛ دایرکتوری ریشه دارای عمق ۰،
زیردایرکتوریهای مستقیم آن دارای عمق ۱ و بههمین ترتیب ادامه مییابد .
این قابلیت در تولید خروجیهای درختی با فاصلهگذاری مناسب بسیار کاربرد
دارد . همچنین این کلاس دارای قابلیتهای کنترلی مانند disable_recursion_pending() است که امکان توقف موقت ورود به زیرشاخهی جاری را فراهم میکند .
بررسی نوع و ویژگیهای ورودیها
هر ورودی از نوع directory_entry
که توسط تکرارگرها بازگردانده میشود، مجموعهی کاملی از متدها را برای
بررسی ویژگیهای فایل یا دایرکتوری مربوطه در اختیار برنامهنویس قرار
میدهد . مهمترین این متدها عبارتند از: is_directory() برای تشخیص دایرکتوری بودن، is_regular_file() برای تشخیص فایل معمولی بودن (که برای عملیات خواندن و نوشتن کاربرد دارد)، is_symlink() برای تشخیص پیوند سمبلیک، و همچنین متدهای دیگری مانند is_block_file() و is_character_file() . همچنین متد file_size() برای دریافت حجم فایل و last_write_time()
برای دریافت زمان آخرین تغییر، از جمله امکانات مفید دیگر این کلاس هستند .
این متدها در دو نسخه وجود دارند: یکی که در صورت بروز خطا استثنا پرتاب
میکند و دیگری که یک شیء error_code
را برای بررسی دریافت میکند . وجود این ابزارها به برنامهنویس اجازه
میدهد تا منطق پیچیدهای مانند فیلتر کردن فایلها بر اساس نوع، اندازه یا
زمان تغییر را بهسادگی پیادهسازی کند و به عنوان مثال، تنها فایلهای
متنی بزرگتر از یک حد مشخص را پردازش نماید .
کلیدواژه ها : std::filesystem-ایجاد دایرکتوری در C++-create_directory-create_directories-پیمایش دایرکتوری C++-directory_iterator-recursive_directory_iterator-std::filesystem depth-directory_entry-بررسی نوع فایل C++-is_regular_file-is_directory-پیمایش بازگشتی پوشه-C++17 filesystem-مدیریت دایرکتوری در C++-آموزش std::filesystem-کپی ویژگیهای دایرکتوری