Python programlarımız çalıştığında oluşturduğumuz değişkenler, listeler, sözlükler ve diğer veri yapıları genellikle program sona erdiğinde kaybolur. Verilerin program çalışması bittikten sonra da saklanması veya programlar arasında veri alışverişi yapılması gerektiğinde, dosya işlemleri (File I/O — Input/Output) devreye girer. Dosya işlemleri, verileri sabit diskinizdeki (veya başka bir depolama birimindeki) dosyalara yazmamızı ve bu dosyalardaki verileri okuyarak programımıza geri yüklememizi sağlar.

Web sunucusu loglarını analiz etmekten, kullanıcı ayarlarını kaydetmeye, büyük veri setlerini işlemekten, programlar arası veri transferine kadar birçok alanda dosya işlemleri temel bir gerekliliktir. Python, dosyalarla çalışmak için oldukça basit, anlaşılır ve güçlü yerleşik araçlar sunar.

Bu rehberde, Python’da dosyaların nasıl açılacağını (open() fonksiyonu), farklı dosya modlarını (okuma, yazma, ekleme vb.), dosyalardan veri okumanın çeşitli yollarını (read(), readline(), readlines(), iterasyon), dosyalara veri yazmayı (write(), writelines()), dosyaları güvenli bir şekilde kapatmanın önemini ve bunun için en iyi pratik olan with ifadesini detaylı bir şekilde inceleyeceğiz. Ayrıca, metin ve ikili (binary) dosyalar arasındaki farklara, karakter kodlama (encoding) sorunlarına ve bazı temel dosya sistemi operasyonlarına da değineceğiz.

Bölüm 1: Dosya Nedir? Temel Kavramlar
Bilgisayar bağlamında bir dosya, disk gibi kalıcı bir depolama ortamında saklanan, isimlendirilmiş bir bilgi koleksiyonudur. Bu bilgi metin, resim, video, program kodu, ses veya başka herhangi bir veri türü olabilir.

Python’da dosyalarla çalışırken genellikle iki ana dosya türüyle karşılaşırız:

Metin Dosyaları (Text Files): İnsan tarafından okunabilir karakter dizileri (harfler, rakamlar, semboller) içerirler. Genellikle .txt, .py, .csv, .html, .json, .xml gibi uzantılara sahiptirler. Python, metin dosyalarını okurken ve yazarken karakterlerin belirli bir karakter kodlamasına (encoding) göre yorumlanması veya kodlanması gerektiğini varsayar (örneğin, UTF-8, ASCII, ISO-8859-9).
İkili Dosyalar (Binary Files): Ham byte dizileri içerirler ve belirli bir karakter kodlamasına göre yorumlanmazlar. Resim dosyaları (.jpg, .png), ses/video dosyaları (.mp3, .mp4), çalıştırılabilir programlar (.exe, .dll), sıkıştırılmış dosyalar (.zip, .gz) ve Python'un pickle modülü ile kaydedilen nesneler ikili dosyalara örnektir. Bu dosyalarla çalışırken verileri byte byte okur ve yazarız.
Dosya türü, dosyayı açarken ve okuma/yazma işlemleri yaparken kullanacağımız yöntemleri etkiler.

Bölüm 2: Dosya Açma: open() Fonksiyonu
Python’da bir dosya üzerinde okuma veya yazma işlemi yapmadan önce onu açmamız gerekir. Bu işlem için yerleşik open() fonksiyonu kullanılır.

Temel Sözdizimi:

file_object = open(file, mode='r', encoding=None, errors=None)
Parametreler:

file: Açılacak dosyanın yolu (path). Bu, sadece dosya adı (eğer dosya Python script'i ile aynı dizindeyse) veya tam bir dosya yolu (örn: /home/user/belgeler/dosya.txt veya C:\Users\User\Documents\dosya.txt) olabilir. Dosya yollarında ters bölü çizgisi () kullanılıyorsa, ya çift ters bölü çizgisi (\) ya da ham string (raw string - r"C:\Users...") kullanılmalıdır.
mode (İsteğe bağlı): Dosyanın hangi amaçla açılacağını belirten bir karakter dizisidir. Varsayılan mod 'r' (okuma)'dır. En yaygın modlar şunlardır:ModAçıklamaDosya YoksaDosya Varsaİmleç Konumu'r'Okuma (Read - Varsayılan): Dosyayı sadece okuma amacıyla açar.Hata (FileNotFoundError)İçeriği okunur.Başlangıç'w'Yazma (Write): Dosyayı sadece yazma amacıyla açar.Yeni dosya oluşturur.İçeriğini tamamen siler (üzerine yazar)!Başlangıç'a'Ekleme (Append): Dosyayı yazma amacıyla açar, ancak mevcut içeriği silmez. Yazma işlemi dosyanın sonundan başlar.Yeni dosya oluşturur.İçeriği korunur.Dosya Sonu'x'Özel Oluşturma (Exclusive Creation): Dosyayı sadece yazma amacıyla oluşturur.Yeni dosya oluşturur.Hata (FileExistsError)Başlangıç'+'Güncelleme (Okuma ve Yazma): Yukarıdaki modlardan birine eklenir ('r+', 'w+', 'a+'). Hem okuma hem yazma izni verir. r+: Dosya olmalı, imleç başta. w+: İçeriği siler veya oluşturur, imleç başta. a+: Oluşturur veya sona ekler, imleç sonda (okuma için başa alınabilir).Moda bağlı (w+/a+ oluşturur, r+ hata verir)Moda bağlı (w+ siler)Moda bağlı'b'İkili Mod (Binary): Yukarıdaki modlardan birine eklenir ('rb', 'wb', 'ab', 'rb+' vb.). Dosyanın ikili (byte) olarak işleneceğini belirtir. Metin dosyaları dışındaki (resim, ses vb.) dosyalar için kullanılır.---'t'Metin Modu (Text - Varsayılan): Mod belirtilmezse veya 'b' eklenmezse varsayılan olarak kullanılır. Dosyanın metin olarak işleneceğini, karakter kodlamasının önemli olduğunu belirtir.---
encoding (İsteğe bağlı, Metin Modunda Önemli): Metin dosyaları için kullanılacak karakter kodlamasını belirtir. Eğer belirtilmezse, Python işletim sisteminin varsayılan kodlamasını kullanır (bu Windows'ta genellikle cp1254 gibi yerel bir kodlama, Linux/macOS'ta ise genellikle utf-8 olabilir). Farklı sistemlerde tutarlılık ve Türkçe karakterler gibi özel karakterlerin doğru işlenmesi için encoding='utf-8' belirtmek genellikle en iyi pratiktir.
errors (İsteğe bağlı): Kodlama/çözme hatalarıyla nasıl başa çıkılacağını belirtir (örn: 'strict' (varsayılan, hata verir), 'ignore' (hatalı karakterleri atlar), 'replace' (hatalıları bir karakterle değiştirir)).
open() fonksiyonu başarılı olursa, dosya üzerinde işlem yapmak için kullanacağımız bir dosya nesnesi (file object) veya dosya tanıtıcısı (file handle) döndürür.

try:
# Var olan bir metin dosyasını okuma modunda UTF-8 ile açma
dosya_okuma = open("ornek.txt", mode="r", encoding="utf-8")
print("ornek.txt okuma modunda başarıyla açıldı.")
# Yazma modunda yeni bir dosya açma (varsa üzerine yazılır)
dosya_yazma = open("yeni_dosya.log", mode="w", encoding="utf-8")
print("yeni_dosya.log yazma modunda başarıyla açıldı/oluşturuldu.")
# İkili modda resim dosyası yazma
# dosya_binary = open("resim.jpg", mode="wb")
# print("resim.jpg ikili yazma modunda başarıyla açıldı.")
# 'x' modu ile dosya oluşturma (varsa hata verir)
# dosya_ozel = open("benzersiz_dosya.txt", mode="x")
# print("benzersiz_dosya.txt başarıyla oluşturuldu.")
# Hatalı durum: Dosya bulunamadı
# dosya_hata = open("olmayan_dosya.txt", mode="r")

Olası hataları yakalama

except FileNotFoundError:
print("Hata: Belirtilen dosya bulunamadı!")
except FileExistsError:
print("Hata: Dosya zaten var, 'x' modu ile açılamaz!")
except PermissionError:
print("Hata: Dosya açma/yazma izni yok!")
except Exception as e:
print(f"Beklenmedik bir hata oluştu: {e}")
finally:
# Dosyaların kapatılması gerekir (bu kısım 'with' ile daha iyi yapılır)
if 'dosya_okuma' in locals() and not dosya_okuma.closed:
dosya_okuma.close()
print("Okuma dosyası kapatıldı.")
if 'dosya_yazma' in locals() and not dosya_yazma.closed:
dosya_yazma.close()
print("Yazma dosyası kapatıldı.")
# Diğer dosyalar için de benzer kontroller...
open() ile açılan dosyaların işiniz bittikten sonra mutlaka kapatılması (close()) gerekir. Aksi takdirde, yazılan veriler diske tam olarak aktarılmayabilir veya sistem kaynakları (dosya tanıtıcıları) gereksiz yere meşgul edilebilir. Dosya kapatmayı garanti altına almanın en iyi yolu with ifadesidir (Bölüm 5).

Bölüm 3: Dosyalardan Veri Okuma
Bir dosyayı okuma modlarından biriyle ('r', 'r+', 'rb' vb.) açtıktan sonra, içeriğini okumak için çeşitli metotlar kullanabiliriz.

Aşağıdaki örnekler için siir.txt adında şu içeriğe sahip bir dosyamız olduğunu varsayalım:

Uçurtmam bulutlardan yüce,
Zıpzıplarım pıtır pıtır,
İp atlarım hop hop,
Ne güzeldir oynamak.
3.1. read(size=-1) Metodu
Ne Yapar: Dosyanın mevcut konumundan itibaren belirtilen size kadar karakteri (metin modunda) veya byte'ı (ikili modda) okur ve bir string (metin) veya bytes nesnesi (ikili) olarak döndürür.
Eğer size belirtilmezse veya negatif bir değer verilirse (varsayılan -1), dosyanın kalanının tamamını okur.
Dosyanın sonuna ulaşıldığında boş bir string ('') veya boş bir bytes nesnesi (b'') döndürür.
read() metodunu argümansız kullanmak, dosyanın tamamını belleğe yükler. Çok büyük dosyalar için bu durum bellek sorunlarına yol açabilir. Büyük dosyaları okurken dikkatli kullanılmalıdır.

Önce dosyayı açalım (with ifadesi önerilir, sonraki bölüme bakınız)

f_read = open("siir.txt", "r", encoding="utf-8")

Tüm içeriği oku

icerik_tamami = f_read.read()
print("--- read() ile Tamamı ---")
print(icerik_tamami)
print("------------------------")

İmleç artık dosya sonunda olduğu için tekrar okuma boş döner

tekrar_oku = f_read.read()
print(f"Tekrar okuma denemesi: '{tekrar_oku}'")

Dosyayı kapatıp tekrar açarak imleci başa alalım

f_read.close()
f_read = open("siir.txt", "r", encoding="utf-8")

İlk 10 karakteri oku

ilk_10 = f_read.read(10)
print(f"\nİlk 10 karakter: '{ilk_10}'") # 'Uçurtmam b'

Kalan kısmı oku

kalan_kisim = f_read.read()
print("\nKalan Kısım:")
print(kalan_kisim)
f_read.close()
3.2. readline(size=-1) Metodu
Ne Yapar: Dosyanın mevcut konumundan itibaren tek bir satırı okur ve string olarak döndürür. Satır sonu karakteri (\n) de string'e dahil edilir.
Eğer isteğe bağlı size argümanı verilirse, o satırdan en fazla size kadar karakter/byte okur.
Dosyanın sonuna ulaşıldığında boş bir string ('') döndürür.
f_readline = open("siir.txt", "r", encoding="utf-8")
print("--- readline() ile Satır Satır ---")
satir1 = f_readline.readline()
print(f"Satır 1: {satir1.strip()}") # strip() ile sondaki \n'i kaldırabiliriz
satir2 = f_readline.readline()
print(f"Satır 2: {satir2.strip()}")
satir3 = f_readline.readline()
print(f"Satır 3: {satir3.strip()}")
satir4 = f_readline.readline()
print(f"Satır 4: {satir4.strip()}")
satir5 = f_readline.readline() # Dosya sonu
print(f"Satır 5 (Boş mu?): '{satir5}'") # ''
f_readline.close()
readline() genellikle dosyayı satır satır işlemek için bir while döngüsü içinde kullanılır:

f_loop = open("siir.txt", "r", encoding="utf-8")
print("\n--- readline() ve while Döngüsü ---")
while True:
satir = f_loop.readline()
if not satir: # Eğer boş string döndüyse dosya sonuna gelinmiştir
break
print(f"> {satir.strip()}")
f_loop.close()
3.3. readlines() Metodu
Ne Yapar: Dosyanın tüm satırlarını okur ve her satırın bir string olduğu bir liste döndürür. Her string, satır sonu karakterini (\n) içerir.
readlines() da read() gibi dosyanın tamamını belleğe yükler. Çok büyük dosyalar için bellek sorunlarına neden olabilir.

f_readlines = open("siir.txt", "r", encoding="utf-8")
tum_satirlar_liste = f_readlines.readlines()
print("\n--- readlines() ile Tüm Satırlar (Liste) ---")
print(tum_satirlar_liste)

['Uçurtmam bulutlardan yüce,\n', 'Zıpzıplarım pıtır pıtır,\n', 'İp atlarım hop hop,\n', 'Ne güzeldir oynamak.\n']

print("\nListe Elemanları:")
for satir in tum_satirlar_liste:
print(f"- {satir.strip()}")
f_readlines.close()
3.4. Dosya Nesnesi Üzerinde İterasyon (En İyi Yöntem)
Ne Yapar: Dosya nesneleri doğrudan yinelenebilir (iterable) olduğu için, bir for döngüsü kullanarak dosyayı satır satır okuyabilirsiniz.
Bu yöntem, Python’da bir metin dosyasını satır satır işlemenin en bellek verimli ve en “Pythonic” yoludur. Çünkü satırları tek tek okur, tüm dosyayı belleğe yüklemez.
f_iter = open("siir.txt", "r", encoding="utf-8")
print("\n--- Dosya Üzerinde Doğrudan İterasyon ---")
for satir_numarasi, satir in enumerate(f_iter, 1): # enumerate ile satır numarası da alalım
print(f"{satir_numarasi}: {satir.strip()}")
f_iter.close()

Bu yöntem en çok tercih edilendir.

Bölüm 4: Dosyalara Veri Yazma
Bir dosyayı yazma veya ekleme modlarından biriyle ('w', 'a', 'x', 'w+', 'a+', 'wb' vb.) açtıktan sonra, içine veri yazmak için şu metotları kullanırız:

4.1. write(string) Metodu
Ne Yapar: Verilen string'i dosyaya yazar.
Dönüş Değeri: Yazılan karakter sayısını (integer) döndürür.
Önemli Not: write() metodu otomatik olarak satır sonu karakteri (\n) eklemez. Farklı satırlara yazmak istiyorsanız, string'in sonuna \n karakterini manuel olarak eklemelisiniz.

'w' modu ile açalım (varsa içeriği silinecek)

f_write = open("cikti.txt", "w", encoding="utf-8")
metin1 = "Bu ilk satırımız."
metin2 = "Bu da ikinci satır."
metin3 = "Üçüncü satır."
karakter_sayisi1 = f_write.write(metin1)
f_write.write("\n") # Yeni satır karakterini manuel ekle!
karakter_sayisi2 = f_write.write(metin2 + "\n") # String sonuna ekleyebiliriz
karakter_sayisi3 = f_write.write(metin3) # Son satırda \n olmayabilir
print(f"Yazılan karakter sayıları: {karakter_sayisi1}, {karakter_sayisi2}, {karakter_sayisi3}")
f_write.close() # Yazma işlemlerinden sonra kapatmak ÇOK ÖNEMLİ!

Oluşan cikti.txt dosyasının içeriği:

Bu ilk satırımız.

Bu da ikinci satır.

Üçüncü satır.

'a' modu ile açıp ekleme yapalım

f_append = open("cikti.txt", "a", encoding="utf-8")
f_append.write("\nBu eklenen dördüncü satır.")
f_append.close()

cikti.txt dosyasının son hali:

Bu ilk satırımız.

Bu da ikinci satır.

Üçüncü satır.

Bu eklenen dördüncü satır.

4.2. writelines(list_of_strings) Metodu
Ne Yapar: Argüman olarak verilen string listesindeki (veya başka bir yinelenebilirdeki) her bir string’i sırayla dosyaya yazar.
Önemli Not: writelines() da otomatik olarak satır sonu karakteri (\n) eklemez. Eğer her string'in ayrı bir satırda olmasını istiyorsanız, listedeki string'lerin sonuna \n karakterini önceden eklemiş olmanız gerekir.
Dönüş Değeri: None döndürür.
satirlar = [
"Liste elemanı 1\n", # Satır sonu karakterleri dahil
"Liste elemanı 2\n",
"Liste elemanı 3"
]
f_writelines = open("liste_cikti.txt", "w", encoding="utf-8")
f_writelines.writelines(satirlar)
f_writelines.close()

liste_cikti.txt içeriği:

Liste elemanı 1

Liste elemanı 2

Liste elemanı 3

Bölüm 5: Dosyaları Kapatmak ve with İfadesi
5.1. Neden Dosyaları Kapatmalıyız?
open() ile açılan bir dosya nesnesi, işletim sisteminden bir kaynak (dosya tanıtıcısı) kullanır. Ayrıca, Python performansı artırmak için dosyalara yapılan yazma işlemlerini hemen diske yazmak yerine bir tampon (buffer) bellekte biriktirebilir. Dosyayı close() metodu ile kapatmak şu nedenlerle önemlidir:

Tamponu Boşaltmak (Flushing): close() çağrıldığında, tamponda bekleyen tüm verilerin diske yazılması garanti altına alınır. Dosyayı kapatmadan program biterse veya bir hata oluşursa, tampondaki veriler kaybolabilir.
Kaynakları Serbest Bırakmak: Dosya tanıtıcısı gibi işletim sistemi kaynaklarını serbest bırakır. Çok sayıda dosyayı açık unutup kapatmamak, sistemin kaynak sınırlarına ulaşmasına ve programın hata vermesine neden olabilir.
Diğer Programların Erişimi: Bazı işletim sistemlerinde, bir program tarafından yazma modunda açık tutulan bir dosyaya başka programların erişimi kısıtlanabilir. Dosyayı kapatmak bu kısıtlamayı kaldırır.
5.2. close() Metodu ve Sorunları
Dosyayı kapatmanın temel yolu file_object.close() metodunu çağırmaktır. Ancak manuel olarak close() çağırmanın bir sorunu vardır: Eğer dosya işlemleri sırasında bir hata oluşursa, close() metodunun çağrıldığı satıra ulaşılamayabilir ve dosya açık kalabilir.

Bu sorunu çözmek için geleneksel yöntem try...finally bloğu kullanmaktır:

try...finally ile dosya kapatmayı garanti altına alma (Eski Yöntem)

f = None # Değişkeni önce tanımla
try:
f = open("eski_yontem.txt", "w", encoding="utf-8")
# Dosya işlemleri...
f.write("Merhaba ")
# Belki burada bir hata oluşur? Örneğin: 10 / 0
f.write("Dünya!")
except Exception as e:
print(f"Bir hata oluştu: {e}")
finally:
# Bu blok hata olsa da olmasa da çalışır
if f and not f.closed: # Dosya başarıyla açıldıysa ve hala açıksa
f.close()
print("Dosya (finally bloğunda) kapatıldı.")
try...finally çalışır, ancak biraz uzun ve tekrarlıdır.

5.3. with İfadesi (Context Manager — En İyi Pratik)
Python, dosyaları ve diğer kaynakları yönetmek için çok daha temiz, güvenli ve okunabilir bir yol sunar: with ifadesi. with ifadesi, bir bağlam yöneticisi (context manager) protokolünü uygular.

Dosya nesneleri yerleşik olarak bağlam yöneticisidir. with ifadesi ile bir dosya açıldığında:

Dosya otomatik olarak açılır ve dosya nesnesi belirtilen değişkene atanır.
with bloğu içindeki kodlar çalıştırılır.
with bloğundan çıkıldığında (normal şekilde tamamlansa da, bir hata nedeniyle kesilse de, bir return veya break ile çıkılsa da) dosya otomatik olarak ve güvenli bir şekilde kapatılır.
Sözdizimi:

with open(file, mode, encoding=...) as dosya_degiskeni:
# dosya_degiskeni'ni kullanarak dosya işlemleri yap
# Bu blok içinde dosya açıktır
# ...

Bu satıra gelindiğinde (bloktan çıkıldığında) dosya otomatik olarak kapatılmıştır.

Artık dosya_degiskeni üzerinden işlem yapılamaz (dosya kapalı).

Örnekler:

with ile dosya okuma (en iyi pratik)

print("\n--- with ile Okuma ---")
try:
with open("siir.txt", "r", encoding="utf-8") as f_oku:
for satir in f_oku:
print(f"- {satir.strip()}")
# Bu noktada f_oku dosyası otomatik olarak kapandı.
print("Okuma tamamlandı, dosya kapandı.")
except FileNotFoundError:
print("Hata: siir.txt bulunamadı.")

with ile dosya yazma

print("\n--- with ile Yazma ---")
yazilacaklar = ["Satır 1\n", "Satır 2\n", "Satır 3"]
try:
with open("with_cikti.txt", "w", encoding="utf-8") as f_yaz:
f_yaz.write("Bu ilk yazı.\n")
f_yaz.writelines(yazilacaklar)
# Bloktan çıkınca dosya otomatik kapanacak ve tampon boşaltılacak.
print("Yazma tamamlandı, dosya kapandı.")
except Exception as e:
print(f"Yazma sırasında hata: {e}")

with bloğu dışında dosyanın kapalı olduğunu kontrol etme

print(f_oku.closed) # True (Eğer önceki blok çalıştıysa)

print(f_yaz.closed) # True (Eğer önceki blok çalıştıysa)

Python’da dosya işlemleri yaparken her zaman with ifadesini kullanmanız şiddetle tavsiye edilir. Kodu daha kısa, daha okunaklı yapar ve dosyanın her koşulda düzgün bir şekilde kapatılmasını garanti ederek olası hataları ve kaynak sızıntılarını önler. Manuel close() veya try...finally kullanmaktan çok daha iyidir.

Bölüm 6: Dosya İmleci (Pointer) ve seek(), tell()
Python bir dosyayı okurken veya yazarken, dosya içinde nerede olduğunu takip eden görünmez bir imleç (pointer veya cursor) tutar. Okuma ve yazma işlemleri bu imlecin bulunduğu yerden başlar ve işlem yapıldıkça imleç ilerler.

tell() Metodu: İmlecin dosya içindeki mevcut konumunu (dosyanın başından itibaren byte cinsinden uzaklığını) döndürür.
seek(offset, whence=os.SEEK_SET) Metodu: İmlecin konumunu değiştirir.
offset: Kaydırılacak byte sayısı.
whence (İsteğe bağlı): Referans noktasını belirtir (os modülünden import edilmelidir):
os.SEEK_SET (veya 0 - Varsayılan): Dosyanın başından itibaren offset kadar ileri git.
os.SEEK_CUR (veya 1): Mevcut konumdan itibaren offset kadar ileri (pozitif) veya geri (negatif) git.
os.SEEK_END (veya 2): Dosyanın sonundan itibaren offset kadar geri git (genellikle negatif offset kullanılır).
seek() ve tell() genellikle ikili (binary) dosyalarla çalışırken veya dosyanın belirli bir bölümüne rastgele erişim gerektiğinde daha kullanışlıdır. Metin dosyalarında karakter kodlaması ve satır sonu karakterlerinin farklı sistemlerdeki temsili nedeniyle byte offset'leriyle çalışmak karmaşık olabilir ve genellikle önerilmez (metin dosyalarında genellikle baştan sona okuma tercih edilir).

import os

Örnek (with ile)

try:
with open("ornek_seek.txt", "w+", encoding="utf-8") as f: # w+ hem yazma hem okuma, içeriği siler
f.write("0123456789abcdef")
# Başlangıç konumu
print(f"Yazma sonrası konum: {f.tell()}") # Genellikle dosya sonu (16)
# Başa dönme (okumak için)
f.seek(0) # veya f.seek(0, os.SEEK_SET)
print(f"Seek(0) sonrası konum: {f.tell()}") # 0
# İlk 5 karakteri oku
ilk_bes = f.read(5)
print(f"İlk 5 okundu: '{ilk_bes}'") # '01234'
print(f"Okuma sonrası konum: {f.tell()}") # 5
# Mevcut konumdan 3 byte ileri git
f.seek(3, os.SEEK_CUR)
print(f"Seek(3, CUR) sonrası konum: {f.tell()}") # 8
# Kalanı oku
kalan = f.read()
print(f"Kalan okundu: '{kalan}'") # '89abcdef'
# Dosya sonundan 5 byte geriye gitme
f.seek(-5, os.SEEK_END)
print(f"Seek(-5, END) sonrası konum: {f.tell()}") # 11 (16 - 5)
son_bes = f.read()
print(f"Sondan 5 okundu: '{son_bes}'") # 'bcdef'
except Exception as e:
print(f"Seek/Tell hatası: {e}")
Bölüm 7: İkili (Binary) Dosyalarla Çalışma
Resim, ses, video gibi metin olmayan dosyalarla veya yapılandırılmış verileri (örn: pickle ile kaydedilmiş nesneler) içeren dosyalarla çalışırken ikili modu ('b') kullanırız.

İkili modda açılan dosyalardan okunan veri bytes türündedir.
İkili modda dosyalara yazılan veri de bytes türünde olmalıdır. String'leri byte'a çevirmek için str.encode(encoding), byte'ları string'e çevirmek için bytes.decode(encoding) kullanılır (ancak ikili dosyaların içeriği genellikle doğrudan metin olarak decode edilmez).
encoding parametresi ikili modda kullanılmaz.
Örnek: Basit bir byte dizisini ikili dosyaya yazıp okuma

İkili dosyaya yazma

try:
with open("veri.bin", "wb") as f_bin_w: # 'wb' modu
byte_dizisi = b'\x48\x65\x6c\x6c\x6f' # 'Hello' kelimesinin byte temsili
sayi_bytes = (258).to_bytes(2, byteorder='big') # 258 sayısını 2 byte olarak yazalım
f_bin_w.write(byte_dizisi)
f_bin_w.write(sayi_bytes)
print("İkili dosya 'veri.bin' yazıldı.")
except Exception as e:
print(f"İkili yazma hatası: {e}")

İkili dosyadan okuma

try:
with open("veri.bin", "rb") as f_bin_r: # 'rb' modu
okunan_ilk_5_byte = f_bin_r.read(5)
okunan_sonraki_2_byte = f_bin_r.read(2)
print(f"\nOkunan ilk 5 byte: {okunan_ilk_5_byte}") # b'Hello'
# İsterseniz decode edebilirsiniz (eğer metin olduğunu biliyorsanız)
print(f"Decode edilmiş hali: {okunan_ilk_5_byte.decode('ascii')}") # Hello
# Okunan sayı byte'larını integer'a çevirme
okunan_sayi = int.from_bytes(okunan_sonraki_2_byte, byteorder='big')
print(f"Okunan sonraki 2 byte: {okunan_sonraki_2_byte}") # b'\x01\x02'
print(f"Integer'a çevrilmiş hali: {okunan_sayi}") # 258
except FileNotFoundError:
print("Hata: veri.bin bulunamadı.")
except Exception as e:
print(f"İkili okuma hatası: {e}")
Gerçek dünya uygulamalarında resim veya ses dosyalarıyla çalışırken genellikle Pillow, NumPy, SciPy gibi kütüphaneler kullanılır, ancak temel okuma/yazma işlemleri yine ikili modda yapılır.

Bölüm 8: Dosya Sistemi İşlemleri (os Modülü)
Dosyaların içeriğini okuyup yazmanın yanı sıra, dosyaların kendisiyle (var olup olmadığını kontrol etme, silme, yeniden adlandırma vb.) veya bulundukları dizinlerle ilgili işlemler yapmak için Python’un os modülü kullanılır. os.path alt modülü özellikle dosya yollarıyla ilgili işlemlerde çok kullanışlıdır.

Bazı yaygın os ve os.path fonksiyonları:

os.path.exists(path): Belirtilen yol (dosya veya dizin) var mı? (True/False)
os.path.isfile(path): Belirtilen yol bir dosya mı? (True/False)
os.path.isdir(path): Belirtilen yol bir dizin mi? (True/False)
os.path.getsize(path): Dosyanın boyutunu byte cinsinden döndürür.
os.rename(src, dst): Dosyayı veya dizini yeniden adlandırır veya taşır.
os.remove(path): Belirtilen dosyayı siler. (Dizinleri silmek için os.rmdir veya os.removedirs / shutil.rmtree)
os.listdir(path='.'): Belirtilen dizindeki dosya ve dizinlerin isimlerini içeren bir liste döndürür (varsayılan: geçerli dizin).
os.makedirs(path, exist_ok=False): Belirtilen dizini ve gerekli tüm üst dizinleri oluşturur. exist_ok=True ise dizin zaten varsa hata vermez. (Tek bir dizin oluşturmak için os.mkdir).
os.getcwd(): Geçerli çalışma dizinini (Current Working Directory) döndürür.
os.chdir(path): Geçerli çalışma dizinini değiştirir.
import os
dosya_adi = "kontrol.txt"
dizin_adi = "yeni_dizin/alt_dizin"

Dosya var mı kontrolü

if os.path.exists(dosya_adi):
print(f"'{dosya_adi}' dosyası mevcut.")
print(f"Boyutu: {os.path.getsize(dosya_adi)} bytes")
# os.remove(dosya_adi) # İstersek silebiliriz
# print(f"'{dosya_adi}' silindi.")
else:
print(f"'{dosya_adi}' dosyası bulunamadı.")
# Yeni dosya oluşturalım
with open(dosya_adi, "w") as f:
f.write("Kontrol dosyası içeriği.")
print(f"'{dosya_adi}' oluşturuldu.")

Dizin oluşturma

try:
os.makedirs(dizin_adi, exist_ok=True) # Varsa hata verme
print(f"'{dizin_adi}' dizini oluşturuldu veya zaten mevcut.")
except OSError as e:
print(f"Dizin oluşturma hatası: {e}")

Geçerli dizini listeleme

print("\nGeçerli Dizindeki Öğeler:")
for oge in os.listdir('.'): # '.' geçerli dizin anlamına gelir
print(f"- {oge} {'(Dizin)' if os.path.isdir(oge) else '(Dosya)'}")
Sonuç
Python’da dosya işlemleri, verileri kalıcı hale getirmenin ve programlar arasında bilgi alışverişi yapmanın temelini oluşturur. open() fonksiyonu ile dosyaları uygun modlarda (okuma, yazma, ekleme, metin, ikili) açmak ilk adımdır. read(), readline(), readlines() ve dosya üzerinde doğrudan iterasyon gibi yöntemlerle dosya içerikleri okunabilirken, write() ve writelines() ile dosyalara veri yazılabilir.

Dosyaları işiniz bittiğinde kapatmanın önemi büyüktür ve bu işlemi hatasız ve zarif bir şekilde gerçekleştirmek için with ifadesini kullanmak kesinlikle en iyi pratiktir. with, dosyanın her koşulda otomatik olarak kapatılmasını sağlayarak kaynak sızıntılarını ve veri kaybını önler.

Metin dosyalarıyla çalışırken karakter kodlamasına (özellikle encoding='utf-8' kullanımına) dikkat etmek, ikili dosyalarla çalışırken ise veriyi bytes olarak işlemek gerekir. seek() ve tell() gibi fonksiyonlar dosya içinde gezinmeye olanak tanırken, os modülü dosya sistemi üzerinde daha genel işlemler yapmamızı sağlar.

Bu temel dosya okuma ve yazma becerilerini kavramak, Python ile daha yetenekli ve pratik uygulamalar geliştirmenizin kapısını aralayacaktır.

Abdulkadir Güngör - Kişisel WebSite
Abdulkadir Güngör - Kişisel WebSite
Abdulkadir Güngör - Özgeçmiş
Github
Github
Linkedin