کار با فایل‌ها

اصلاح شده

2026-08-20

خواندن و نوشتن فایل متنی

بازکردن فایل متنی

fhand = open('mbox.txt')
  • خروجی یک handle به فایله، نه محتوای واقعی — برای خوندن ازش استفاده می‌شه
  • اگه فایل وجود نداشته باشه → خطا: FileNotFoundError
حالت کاربرد
'r' خواندن (پیش‌فرض)
'w' نوشتن — ⚠️ محتوای قبلی فایل پاک می‌شه
'a' append — اضافه‌کردن به انتهای فایل، بدون پاک کردن محتوای قبلی
'x' ساخت فایل جدید — اگه از قبل وجود داشته باشه خطا می‌ده

خواندن فایل

  • روش ۱: خط به خط با for (برای فایل‌های بزرگ)
fhand = open('mbox.txt')
count = 0
for line in fhand:
    count += 1
print('Line Count:', count)
  • روش ۲: خواندن کل فایل یکجا (برای فایل‌های کوچک)
fhand = open('mbox.txt')
inp = fhand.read()
print(len(inp))
  • ⚠️ نکته: محتوا رو حتماً توی متغیر ذخیره کنیم، وگرنه با خواندن مجدد از دست می‌ره

جستجو در فایل

fhand = open('mbox.txt')
for line in fhand:
    line = line.rstrip()
    if line.startswith('From:'):
        print(line)
  • rstrip() : حذف فضای خالی سمت راست رشته
  • startswith() : بررسی شروع خط با یک کلمه/رشته خاص

مدیریت خطا

  • به‌جای هاردکد کردن نام فایل، از کاربر می‌گیریم — ولی چون فایل ممکنه وجود نداشته باشه، حتماً با try-except پوشش بدیم
fname = input('Enter the file name: ')
try:
    fhand = open(fname)
except:
    print('File cannot be opened:', fname)
    exit()
  • exit() : خروج کامل از اجرای برنامه اگه فایل باز نشد

نوشتن در فایل

fout = open('output.txt', 'w')
  • پارامتر 'w':
    • اگه فایل وجود داشته باشه → باز می‌شه برای نوشتن (⚠️ محتوای قبلی پاک می‌شه)
    • اگه وجود نداشته باشه → فایل جدید ساخته می‌شه
line1 = "This here's the wattle,\n"
fout.write(line1)

بستن فایل

fout.close()
  • بعد از اتمام کار با فایل، همیشه باید بسته بشه

روش استاندارد و توصیه‌شده

  • روش دستی (باز کردن + close() دستی) رایجه، ولی در عمل استفاده از with توصیه‌شده‌تره
  • مزیت: فایل خودکار بسته می‌شه، حتی اگه وسط کار خطا رخ بده — نیازی به close() دستی نیست
with open('mbox.txt') as fhand:
    for line in fhand:
        print(line.rstrip())
# اینجا فایل خودش بسته شده
with open('output.txt', 'w') as fout:
    fout.write("This here's the wattle,\n")

فایل‌های باینری

تفاوت فایل متنی و باینری

نوع محتوا مثال
متنی (text) کاراکترهای قابل‌خواندن، با encoding رمزگذاری می‌شه .txt، .csv
باینری (binary) دنباله خام بایت‌ها، بدون تفسیر متنی .jpg، .png، .mp3، .pdf، .zip
  • در حالت متنی، پایتون بایت‌ها رو با یک encoding (مثلاً UTF-8) به رشته تبدیل می‌کنه
  • در حالت باینری، هیچ تبدیلی انجام نمی‌شه — داده به‌صورت خام (bytes) خونده/نوشته می‌شه

باز کردن فایل باینری — حرف b

حالت کاربرد
'rb' خواندن باینری
'wb' نوشتن باینری (پاک‌کردن محتوای قبلی)
'ab' append باینری
'xb' ساخت فایل باینری جدید (خطا اگه وجود داشته باشه)

خواندن فایل باینری

with open('image.jpg', 'rb') as f:
    data = f.read()
    print(type(data))   # <class 'bytes'>
    print(len(data))    # تعداد بایت‌ها
  • خروجی از نوع bytes هست، نه str
  • ⚠️ متدهای رشته‌ای مثل .rstrip() یا .startswith('متن') روی bytes فرق دارن (باید با b'...' مقایسه بشن)

نوشتن فایل باینری

data = b'\x89PNG\r\n\x1a\n...'
with open('output.bin', 'wb') as f:
    f.write(data)
  • فقط bytes یا bytearray قابل نوشتنه، نه رشته معمولی

کپی کردن یک فایل باینری (مثال کاربردی)

with open('source.jpg', 'rb') as fin:
    with open('copy.jpg', 'wb') as fout:
        fout.write(fin.read())
  • برای فایل‌های بزرگ بهتره تکه‌تکه (chunk) بخونیم تا حافظه پر نشه:
with open('source.jpg', 'rb') as fin, open('copy.jpg', 'wb') as fout:
    while True:
        chunk = fin.read(4096)   # هر بار ۴۰۹۶ بایت
        if not chunk:
            break
        fout.write(chunk)

تبدیل بین str و bytes

متد کار
str.encode() تبدیل رشته به بایت
bytes.decode() تبدیل بایت به رشته
s = "سلام"
b = s.encode('utf-8')     # str → bytes
print(b)

s2 = b.decode('utf-8')    # bytes → str
print(s2)

نکته مهم: باز کردن فایل متنی به‌جای باینری (و برعکس) خطا می‌ده

  • سعی در خواندن فایل باینری (مثل عکس) با حالت 'r' معمولاً باعث خطای decode می‌شه:
UnicodeDecodeError: 'utf-8' codec can't decode byte...
  • قانون کلی: فایل‌های غیرمتنی (عکس، صدا، فایل فشرده، اجرایی) → همیشه با b

ماژول os

چرا os؟

  • ماژول os برای کار با سیستم‌عامل (فایل، پوشه، مسیر) استفاده می‌شه — چیزی فراتر از خواندن/نوشتن محتوای فایل
  • وارد کردن: import os

بررسی وجود فایل/پوشه

import os

os.path.exists('mbox.txt')     # True / False
os.path.isfile('mbox.txt')     # آیا فایله؟
os.path.isdir('data')          # آیا پوشه‌ست؟

نکته: قبل از باز کردن فایل با open()، می‌شه اول با os.path.exists() چک کرد (هرچند try-except هم روش رایج و ایمن‌تریه)

حذف فایل

os.remove('output.txt')
  • ⚠️ اگه فایل وجود نداشته باشه → خطای FileNotFoundError

تغییر نام / جابه‌جایی فایل

os.rename('old_name.txt', 'new_name.txt')

کار با پوشه‌ها

تابع کار
os.mkdir('folder') ساخت یک پوشه
os.makedirs('a/b/c') ساخت پوشه‌های تودرتو (چند سطحی)
os.rmdir('folder') حذف پوشه (فقط اگه خالی باشه)
os.listdir('.') لیست فایل‌ها و پوشه‌های داخل یک مسیر
os.mkdir('new_folder')
print(os.listdir('.'))

مسیر فعلی و تغییر مسیر

print(os.getcwd())      # مسیر فعلی که برنامه در اون اجرا می‌شه
os.chdir('data')        # تغییر مسیر فعلی به پوشه data

کار با مسیرها — os.path

تابع کار مثال
os.path.join() ساخت مسیر به‌صورت درست (سازگار با ویندوز/لینوکس) os.path.join('data', 'mbox.txt')
os.path.basename() فقط نام فایل از مسیر 'data/mbox.txt''mbox.txt'
os.path.dirname() فقط مسیر پوشه 'data/mbox.txt''data'
os.path.splitext() جدا کردن نام و پسوند فایل 'mbox.txt'('mbox', '.txt')

نکته مهم: به‌جای الحاق دستی رشته‌ها برای مسیر (مثل 'data' + '/' + 'mbox.txt')، همیشه از os.path.join() استفاده بشه — چون در ویندوز جداکننده مسیر \ است نه /

گرفتن اطلاعات فایل

os.path.getsize('mbox.txt')    # حجم فایل بر حسب بایت

پیمایش کامل یک درخت پوشه

for root, dirs, files in os.walk('.'):
    for f in files:
        print(os.path.join(root, f))
  • os.walk() به‌صورت بازگشتی همه‌ی زیرپوشه‌ها و فایل‌ها رو برمی‌گردونه