مدیریت فایلها
هدف این تمرین، پیادهسازی یک کلاس پایتونی برای مدیریت ابتدایی فایلها و پوشهها در سیستم عامل است. این مدیر فایل باید قابلیتهای اصلی زیر را ارائه دهد:
- ایجاد یک پوشهی جدید در یک مسیر مشخص
- ایجاد یک فایل جدید در یک مسیر مشخص
- جستوجوی فایلها بر اساس نام در یک مسیر و زیرشاخههای آن
- حذف یک فایل از یک مسیر مشخص
- بازیابی فایلهای حذفشده
📄 کلاس FileManager
🔹 create_dir(self, name, address)
یک پوشهی جدید با نام
nameدر مسیرaddressمیسازد. خروجیای ندارد. اگر پوشه از قبل وجود داشته باشد، هیچ عملیاتی انجام نمیشود.
🔹 create_file(self, name, address)
یک فایل جدید با نام
nameدر مسیرaddressایجاد میکند. خروجیای ندارد. اگر فایل از قبل وجود داشته باشد، هیچ عملیاتی انجام نمیشود.
🔹 delete(self, name, address)
فایلی با نام
nameرا از مسیرaddressحذف میکند. خروجیای ندارد. اگر فایلی در مسیرaddressبا نامnameوجود نداشته باشد، هیچ عملیاتی انجام نمیشود.
🔹 find(self, name, address)
لیست کامل مسیرهای تمام فایلهای با نام
nameرا از مسیرaddressبه بعد برمیگرداند. جستوجو باید شامل خود مسیرaddressو تمام زیرشاخههای آن باشد. ترتیب مسیرها در لیست خروجی اهمیتی ندارد. اگر هیچ فایلی با این نام یافت نشود، یک لیست خالی[]برگردانده میشود.
🔹 restore(self, name)
آخرین فایلی که با نام
nameحذف شدهاست را بازیابی میکند و به مسیر اصلی خود بازمیگرداند. عملیات بازیابی بهصورت LIFO (Last-In, First-Out) بر اساس نام فایل عمل میکند. محتوای اصلی فایل حذف شده باید پس از بازیابی دستنخورده باقی بماند. اگر هیچ فایلی با نامnameدر لیست فایلهای حذفشده موجود نباشد، هیچ عملیاتی انجام نمیشود.
برای حل این سؤال میتوانید هر فایل و یا پوشهی موقتی که خواستید در کنار فایل کدتان بسازید. فایلهای حذفشده باید در یک سطل زباله (Trash) موقت ذخیره شوند تا امکان بازیابی وجود داشته باشد.
📖 مثال
بخش ۱: ایجاد ساختار
fm = FileManager()
# ساختار اولیه
fm.create_dir('test_fm', '.')
fm.create_dir('test1', 'test_fm')
fm.create_dir('test2', 'test_fm/test1')
# ایجاد فایلها
fm.create_file('document.txt', 'test_fm')
fm.create_file('document.txt', 'test_fm/test1')
fm.create_file('document.txt', 'test_fm/test1/test2')
fm.create_file('another.txt', 'test_fm')
test_fm/
├── test1/
│ ├── test2/
│ │ └── document.txt
│ └── document.txt
├── document.txt
└── another.txt
بخش ۲: جستوجو
print(fm.find('document.txt', 'test_fm'))
📤 خروجی
['test_fm/document.txt', 'test_fm/test1/document.txt', 'test_fm/test1/test2/document.txt']
بخش ۳: حذف فایلها
fm.delete('document.txt', 'test_fm')
fm.delete('document.txt', 'test_fm/test1/')
fm.delete('document.txt', 'test_fm/test1/test2')
test_fm/
├── test1/
│ └── test2/
└── another.txt
بخش ۴: بازیابی فایلها
fm.restore('document.txt')
fm.restore('document.txt')
test_fm/
├── test1/
│ ├── test2/
│ │ └── document.txt
│ └── document.txt
└── another.txt
بخش ۵: جستوجوی مجدد
print(fm.find('document.txt', 'test_fm'))
💡 فایل
test_fm/document.txtبازیابی نشد چون آخرین فایلی نبود که حذف شده بود (LIFO).
['test_fm/test1/document.txt', 'test_fm/test1/test2/document.txt']
✅ پاسخ نهایی
import os
import shutil
import tempfile
class FileManager:
def __init__(self):
# دیکشنری برای ذخیرهی فایلهای حذفشده به صورت LIFO بر اساس نام
self.trash = {}
# پوشهی موقت برای ذخیرهی فایلهای حذفشده
self.trash_dir = tempfile.mkdtemp()
def _get_full_path(self, address, name):
if address == '.':
return name
return os.path.join(address, name)
def create_dir(self, name, address):
path = self._get_full_path(address, name)
if not os.path.exists(path):
os.makedirs(path, exist_ok=True)
def create_file(self, name, address):
path = self._get_full_path(address, name)
if not os.path.exists(path):
open(path, 'w').close()
def delete(self, name, address):
path = self._get_full_path(address, name)
if os.path.exists(path) and os.path.isfile(path):
# ذخیرهسازی در سطل زباله
if name not in self.trash:
self.trash[name] = []
# ایجاد یک نام یکتا برای فایل در سطل زباله
trash_path = os.path.join(self.trash_dir, f"{name}_{len(self.trash[name])}")
# کپی کردن فایل به سطل زباله (با حفظ محتوا)
shutil.copy2(path, trash_path)
self.trash[name].append({'trash_path': trash_path, 'original_path': path})
# حذف فایل اصلی
os.remove(path)
def find(self, name, address):
result = []
for root, dirs, files in os.walk(address):
if name in files:
result.append(os.path.join(root, name))
return result
def restore(self, name):
if name in self.trash and self.trash[name]:
# LIFO: آخرین فایل اضافهشده را بازیابی میکند
entry = self.trash[name].pop()
trash_path = entry['trash_path']
original_path = entry['original_path']
# اطمینان از وجود پوشهی مقصد
os.path.dirname(original_path)
os.makedirs(os.path.dirname(original_path), exist_ok=True)
# بازیابی فایل به مسیر اصلی
shutil.copy2(trash_path, original_path)
# حذف فایل از سطل زباله
os.remove(trash_path)
# اگر لیست خالی شد، کلید را حذف میکنیم
if not self.trash[name]:
del self.trash[name]
📄 main.py
📖 توضیح کد
- سطل زباله (Trash): از یک دیکشنری به نام
trashاستفاده شده که کلید آن نام فایل و مقدار آن لیستی از دیکشنریهای شامل مسیر فایل در سطل زباله و مسیر اصلی است. - روش LIFO: با استفاده از
pop()روی لیست، آخرین فایل اضافهشده برای هر نام بازیابی میشود. - متد
_get_full_path: مسیر کامل یک فایل یا پوشه را با ترکیبaddressوnameمیسازد. - متد
find: با استفاده ازos.walkتمام زیرشاخهها را پیمایش کرده و فایلهای با نام مشخص را پیدا میکند. - متد
delete: قبل از حذف، فایل را باshutil.copy2به سطل زباله کپی میکند تا محتوا حفظ شود. - متد
restore: فایل را از سطل زباله به مسیر اصلی بازمیگرداند.
- از
tempfile.mkdtemp()برای ایجاد پوشهی موقت سطل زباله استفاده شده است- از
shutil.copy2برای کپی کردن فایل با حفظ متادیتا استفاده شده است- فایلهای حذفشده با نامهای یکتا در سطل زباله ذخیره میشوند تا از تداخل جلوگیری شود
🚀 پس از تکمیل کلاس، میتوانید آن را با مثالهای مختلف تست کنید و از صحت عملکرد آن اطمینان حاصل کنید.
نمونهها
fm = FileManager()
fm.create_dir('test_fm', '.')
fm.create_dir('test1', 'test_fm')
fm.create_dir('test2', 'test_fm/test1')
fm.create_file('document.txt', 'test_fm')
fm.create_file('document.txt', 'test_fm/test1')
fm.create_file('document.txt', 'test_fm/test1/test2')
fm.create_file('another.txt', 'test_fm')
sorted(p.replace("\\", "/") for p in fm.find('document.txt', 'test_fm'))
fm.delete('document.txt', 'test_fm')
fm.delete('document.txt', 'test_fm/test1/')
fm.delete('document.txt', 'test_fm/test1/test2')
fm.find('document.txt', 'test_fm')
fm.restore('document.txt')
fm.restore('document.txt')
sorted(p.replace("\\", "/") for p in fm.find('document.txt', 'test_fm'))['test_fm/document.txt', 'test_fm/test1/document.txt', 'test_fm/test1/test2/document.txt'] [] ['test_fm/test1/document.txt', 'test_fm/test1/test2/document.txt']
fm = FileManager()
fm.create_dir('d', '.')
fm.create_file('a.txt', 'd')
with open('d/a.txt', 'w') as handle:
handle.write('keep me')
fm.create_file('a.txt', 'd')
fm.create_dir('d', '.')
open('d/a.txt').read()'keep me'
fm = FileManager()
fm.create_dir('box', '.')
fm.delete('ghost.txt', 'box')
fm.restore('ghost.txt')
fm.find('ghost.txt', 'box')[]
fm = FileManager()
fm.create_dir('keep', '.')
fm.create_file('note.txt', 'keep')
with open('keep/note.txt', 'w') as handle:
handle.write('first draft')
fm.delete('note.txt', 'keep')
fm.find('note.txt', 'keep')
fm.restore('note.txt')
open('keep/note.txt').read()[] 'first draft'
برای نوشتن پاسخ و دریافت امتیاز، ابتدا وارد حساب شوید.
ورود