Nesne Tabanlı Programlama

10 - Dosya İşlemleri

Emre Can Yılmaz

Ondokuz Mayıs Üniversitesi

2024

Dosyalar: Bilgileri Saklama ve Paylaşma

  • Verileri kalıcı olarak saklamak ve daha sonra tekrar kullanmak veya paylaşmak için dosyaları kullanırız.
  • Python, dosyaları okumak, yazmak ve yönetmek için birçok fonksiyon sunar.

Dosya okuma

  • open() fonksiyonu, bir dosyayı açar ve bir dosya nesnesi döndürür.
  • Okuma, yazma, oluşturma gibi farklı modları vardır.
open(dosya_yolu, mod)

open() fonksiyonu modları

  • mod: Dosyayı hangi modda açacağınızı belirten bir string. Yaygın olarak kullanılan modlar şunlardır:
    • 'r': Okuma modu (varsayılan).
    • 'w': Yazma modu. Yoksa oluşturur, varsa içeriği siler.
    • 'a': Ekleme modu. Yoksa oluşturur, varsa sonuna ekler.
    • 'x': Oluşturma modu. Eğer dosya zaten varsa, FileExistsError hatası verir.
    • 'b': İkili (binary) mod. Resim vb okumak için kullanılabilir.
    • 't': Metin (text) modu (varsayılan). Metin dosyalarını okumak veya yazmak için kullanılır.

Örnekler

# "dosya.txt" adlı dosyayı okuma modunda açar
dosya = open("dosya.txt", "r")

# "veri.txt" adlı dosyayı yazma modunda açar. Dosya yoksa oluşturur, varsa içeriğini siler.
dosya = open("veri.txt", "w")

# "log.txt" adlı dosyayı ekleme modunda açar. Dosya yoksa oluşturur.
dosya = open("log.txt", "a")

open() Fonksiyonu - Okuma ve Yazma Modları

  • Bazı durumlarda, bir dosyayı hem okumak hem de yazmak isteyebilirsiniz. Bu gibi durumlar için Python, hem okuma hem de yazma işlemlerine izin veren dosya modları sunar:

  • r+ (Okuma ve Yazma): Dosyayı hem okuma hem de yazma amaçlı açar. Dosya imleci dosyanın başına yerleştirilir. Önemli: Dosya varsa açılır, yoksa hata verir. Varolan dosyanın içeriği silinmez.

  • w+ (Yazma ve Okuma): Dosyayı hem yazma hem de okuma amaçlı açar. Önemli: Dosya varsa içeriği silinir, yoksa yeni bir dosya oluşturulur. Dosya imleci dosyanın başına yerleştirilir.

  • a+ (Ekleme ve Okuma): Dosyayı hem ekleme hem de okuma amaçlı açar. Dosya varsa, yazma işlemleri dosyanın sonuna eklenir ve dosya imleci dosyanın sonuna yerleştirilir. Dosya yoksa, yeni bir dosya oluşturulur.

# r+ modu: Dosya içeriğini oku ve sonra üzerine yaz
with open("dosya.txt", "r+") as dosya:
    icerik = dosya.read()
    print("Dosya içeriği:", icerik)
    dosya.seek(0) # İmleci başa al
    dosya.write("Yeni içerik")
# w+ modu: Dosya içeriğini sil ve yeni içerik yaz, sonra oku
with open("dosya.txt", "w+") as dosya:
    dosya.write("Yepyeni içerik")
    dosya.seek(0)
    yeni_icerik = dosya.read()
    print("Yeni içerik:", yeni_icerik)
# a+ modu: Dosya sonuna ekleme yap ve sonra oku
with open("dosya.txt", "a+") as dosya:
    dosya.write("\nEklenen içerik")
    dosya.seek(0)  # İmleci başa al ki okuyabilelim.
    tum_icerik = dosya.read()
    print("Tüm içerik:", tum_icerik)

Dikkat

r+, w+ ve a+ modlarında, okuma ve yazma işlemleri arasında dosya imlecinin konumuna dikkat etmek önemlidir. seek() metodunu kullanarak imleci istediğiniz konuma getirebilirsiniz. w+ modu, dosyanın içeriğini sildiği için dikkatli kullanılmalıdır.

Türkçe Karakter Sorunu: encoding

  • Farklı işletim sistemleri dosyaları farklı kodlama yöntemleriyle açabilir.
  • İçinde Türkçe karakter (ı, ğ, ş, İ…) bulunan dosyalarda sorun yaşamamak için dosyaları açarken encoding="utf-8" parametresini kullanmak en iyi pratiktir.
# Türkçe karakter desteği ile açma
with open("dosya.txt", "r", encoding="utf-8") as dosya:
    icerik = dosya.read()

Dosya Yolları

  • Dosya yolu, bir dosyanın bilgisayarınızdaki konumunu belirtir.
  • Dosya yolları, işletim sistemine göre farklılık gösterebilir.

Windows:

C:\Users\KullaniciAdi\Belgeler\dosya.txt

Linux/macOS:

/home/kullanici/Belgeler/dosya.txt
/Users/kullanici/Belgeler/dosya.txt

Göreli ve Mutlak Dosya Yolları

  • Mutlak yol: Dosyanın kök dizinden itibaren tam konumunu belirtir.
  • Göreli yol: Dosyanın geçerli çalışma dizinine göre konumunu belirtir.

Örnek:

Geçerli çalışma dizininiz /home/kullanici/projeler/ ise:

  • Mutlak yol: /home/kullanici/projeler/veri.txt
  • Göreli yol: veri.txt veya ./veri.txt

os.path.join() Fonksiyonu

  • Farklı işletim sistemlerinde uyumlu dosya yolları oluşturmak için os.path.join() fonksiyonunu kullanabiliriz.
import os

yol = os.path.join("Belgeler", "dosya.txt")

print(yol) # Windows'ta: Belgeler\dosya.txt, Linux/macOS'ta: Belgeler/dosya.txt

Dosya Kapatma

  • Bir dosya üzerinde işlemlerinizi tamamladıktan sonra, dosyayı kapatmanız önemlidir. Bunu, dosya nesnesinin close() metodunu kullanarak yapabilirsiniz.
  • Dosyaları açık bıraktığınızda, işletim sistemi kaynakları gereksiz yere kullanılır ve potansiyel sorunlara yol açabilir.
  • Süreci tamamlanan dosyaları kapatmak iyi bir programlama pratiğidir.

Örnek

dosya = open("dosya.txt", "r")

# Dosya üzerinde işlemler yapın...

dosya.close()

with ifadesi ile otomatik kapatma

  • with ifadesi, bir dosyayı otomatik olarak kapatmamızı sağlar.
  • with bloğu sona erdiğinde, dosya otomatik olarak kapatılır.

Örnek:

with open("dosya.txt", "r") as dosya:
    # Dosya üzerinde işlemler yapın...

Dosya Okuma İşlemleri

  • Erişilen dosyaları satır satır veya çok satırlı okuma yöntemleri bulunmaktadır.
  • read(), readline(), readlines() fonksiyonu dosyaları okumamızı sağlar.

read() Metodu

  • read() metodu, dosyanın tamamını okur ve tek bir string olarak döndürür.

Örnek: dosya.txt dosyasının içeriği:

Merhaba Dünya!
Bu bir dosya işlemleri örneğidir.
with open("dosya.txt", "r") as dosya:
    icerik = dosya.read()
    print(icerik)
  • read(boyut): İsteğe bağlı olarak, boyut parametresi ile okunacak maksimum karakter sayısı belirtilebilir.
with open("dosya.txt", "r") as dosya:
    ilk_10_karakter = dosya.read(10)
    print(ilk_10_karakter)
  • Çıktı:
Merhaba Dü

readline() Metodu

  • readline() metodu, dosyanın bir satırını okur ve bir string olarak döndürür.
with open("dosya.txt", "r") as dosya:
    satir1 = dosya.readline()
    satir2 = dosya.readline()
    print(satir1, end="")
    print(satir2, end="")

readlines() Metodu

  • readlines() metodu, dosyanın tüm satırlarını okur ve her satırı bir eleman olarak içeren bir liste döndürür.
with open("dosya.txt", "r") as dosya:
    satirlar = dosya.readlines()
    print(satirlar)
    for satir in satirlar:
        print(satir, end="")

Döngü ile Dosya Okuma

  • Bir dosyayı satır satır okumak için, bir for döngüsü kullanabiliriz.
with open("dosya.txt", "r") as dosya:
    for satir in dosya:
        print(satir, end="")

Dosya Yazma

  • Erişilen dosyalara tekil veya çoklu yazma yöntemleri bulunmaktadır.
  • write(), writelines() fonksiyonu dosyaya veri yazmanızı sağlar.

write() Metodu

  • write() metodu, dosyaya bir string yazar.
with open("yazbeni.txt", "w") as dosya:
    dosya.write("Merhaba Dünya!\n")
    dosya.write("Python ile dosya işlemleri.")

writelines() Metodu

  • writelines() metodu, bir string listesi dosyaya yazar.
satirlar = ["Test satır 1\n", "Test satır 2\n", "Test satır 3\n"]

with open("dosya.txt", "w") as dosya:
    dosya.writelines(satirlar)

Dosya Konumlandırma (tell() ve seek())

  • Dosya imlecini (dosyanın neresinde olduğunuzu gösteren işaretçi) hareket ettirmek ve dosyanın belirli bir bölümünü okumak veya yazmak için tell() ve seek() metotlarını kullanabilirsiniz.

tell() Metodu

  • Dosya imlecinin geçerli konumunu (byte cinsinden) döndürür.
  • Dosyanın başlangıcı 0. bayttır.
with open("dosya.txt", "r") as dosya:
    konum = dosya.tell()
    print(f"İmlecin başlangıç konumu: {konum}") # Çıktı: İmlecin başlangıç konumu: 0

    dosya.read(5) # 5 bayt oku
    konum = dosya.tell()
    print(f"5 bayt okuduktan sonra imlecin konumu: {konum}") # Çıktı: 5 bayt okuduktan sonra imlecin konumu: 5

seek() Metodu

  • Dosya imlecini belirtilen konuma taşır.
seek(offset, from_what)
  • offset: Taşınacak bayt sayısı.
  • from_what: Konumun nereden itibaren hesaplanacağını belirtir:
    • 0: Dosyanın başlangıcından (varsayılan)
    • 1: Geçerli konumdan
    • 2: Dosyanın sonundan

seek() Kullanımında Önemli Bir Kural

  • Metin Modu ('r', 'w', 'a'): Dosyayı normal metin modunda açtığınızda, seek() metodu genellikle sadece dosyanın en başına (0) gitmek için kullanılır.

  • İkili Mod ('rb'): Eğer imleci “bulunduğum yerden 5 adım ileri” veya “sondan 10 adım geri” taşımak istiyorsanız, dosyayı Binary (İkili) modda açmanız gerekir.

Özetle

Metin dosyalarında sadece başa sarmak (seek(0)) güvenlidir. Dosya içinde serbestçe ileri-geri gezmek istiyorsanız dosyayı 'rb' modunda açmalısınız.

Örnek: Sondan Geriye Okuma (Binary Mod)

# 'rb' modu: Binary (İkili) Okuma Modu
with open("dosya.txt", "rb") as dosya:
    # 2 parametresi "dosyanın sonunu" temsil eder.
    # Sondan 10 bayt geriye git:
    dosya.seek(-10, 2)

    son_veriler = dosya.read()
    print(son_veriler)

Yapısal Veri Saklama: JSON

  • Şu ana kadar verileri sadece düz metin (.txt) olarak kaydettik.
  • Ancak Python listeleri, sözlükleri veya nesneleri gibi karmaşık yapıları düz metin olarak saklamak ve hatasız geri okumak zordur.
  • Bu tür veriler için dünya standardı olan JSON (JavaScript Object Notation) formatını kullanırız.
  • JSON yapısı, Python’daki sözlük (dictionary) yapısına birebir benzer.

Bir JSON Dosyası Nasıl Görünür?

Bir .json dosyasını Not Defteri ile açtığınızda göreceğiniz yapı şöyledir:

{
  "ad": "Zeynep",
  "soyad": "Yılmaz",
  "yas": 21,
  "ogrenci_mi": true,
  "okul_no": null,
  "aldigi_dersler": [
    "Nesne Tabanlı Programlama",
    "Veri Yapıları",
    "Web Tasarım"
  ],
  "adres": {
    "sehir": "İstanbul",
    "posta_kodu": 34000
  }
}

Python vs JSON Farkları

Yapı Python sözlüklerine (dict) çok benzer ancak:

  • True/False yerine true/false (küçük harf) kullanılır.
  • None yerine null kullanılır.
  • Anahtarlar (keys) mutlaka çift tırnak (“) içinde olmalıdır.

Neden JSON Kullanmalıyız?

  • Veri Tipini Korur: .txt dosyasına sayıları bile string (yazı) olarak yazarsınız. JSON ise sayıyı sayı, listeyi liste, bool değerini (True/False) olduğu gibi saklar.
  • Evrenseldir: Python ile yazdığınız bir JSON dosyasını; JavaScript, C#, Java gibi başka diller de kolayca okuyabilir.
  • Okunabilirdir: İnsan gözüyle okunması ve anlaşılması kolaydır.

Python json Modülü

JSON işlemleri için Python’da dahili olarak gelen json kütüphanesini kullanırız.

Temel iki fonksiyon vardır:

  1. json.dump(): Python verisini (Sözlük, Liste) JSON formatına çevirip dosyaya yazar.
  2. json.load(): JSON dosyasını okuyup tekrar Python verisine (Sözlük, Liste) çevirir.

JSON Dosyası Oluşturma (dump)

import json

# Saklanacak veri (Sözlük/Dictionary)
kullanici = {
    "kullanici_adi": "yazilimci_kiz",
    "seviye": 5,
    "abonelik_aktif": True,
    "ilgi_alanlari": ["Python", "Yapay Zeka", "Web"]
}

# 'w' modunda açıyoruz. Encoding utf-8 ÖNEMLİDİR.
with open("ayarlar.json", "w", encoding="utf-8") as dosya:
    # ensure_ascii=False: Türkçe karakterlerin düzgün görünmesini sağlar
    # indent=4: Dosyanın girintili ve okunaklı yazılmasını sağlar
    json.dump(kullanici, dosya, ensure_ascii=False, indent=4)

print("Veriler ayarlar.json dosyasına kaydedildi.")

Oluşan JSON Dosyası

Yukarıdaki kod çalıştırıldığında ayarlar.json dosyası şu şekilde görünür:

{
    "kullanici_adi": "yazilimci_kiz",
    "seviye": 5,
    "abonelik_aktif": true,
    "ilgi_alanlari": [
        "Python",
        "Yapay Zeka",
        "Web"
    ]
}

JSON Dosyası Okuma (load)

Kaydettiğimiz dosyayı okuyup tekrar Python değişkeni olarak kullanalım.

import json

with open("ayarlar.json", "r", encoding="utf-8") as dosya:
    veri = json.load(dosya) # Dosyayı oku ve Python sözlüğüne çevir

# Artık 'veri' değişkeni normal bir Python sözlüğüdür
print(f"Kullanıcı: {veri['kullanici_adi']}")
print(f"İlgi Alanları: {veri['ilgi_alanlari']}")
print(f"Veri Tipi: {type(veri)}") # <class 'dict'>

Sorular

Soru 1: Bir dosyayı okuyarak satır sayısını ekrana yazdıran kodu yazınız.

Cevap

with open('dosya.txt', 'r') as dosya:
    satirlar = dosya.readlines()
    print(f"Dosyadaki satır sayısı: {len(satirlar)}")

Soru 2: Bir dosyayı okuyup satırları alfabetik sıralayan ve “ordered_lines.txt” ye geri yazan kodu yazın.

Cevap

# Dosyayı aç ve satırları oku
with open('okubeni.txt', 'r', encoding='utf-8') as file:
    satirlar = file.readlines()

# Satırları alfabetik olarak sırala
sirali_satirlar = sorted(satirlar)

# Sıralanmış satırları yeni bir dosyaya yaz
with open('ordered_lines.txt', 'w', encoding='utf-8') as output_file:
    output_file.writelines(sirali_satirlar)

print("Satırlar sıralandı ve 'ordered_lines.txt' dosyasına yazıldı.")

Soru 3: Bir dosyayı okuyup farklı bir dosyaya tersten yazdıran kodu yazın.

Cevap

with open('okubeni.txt', 'r') as file:
    content = file.read()

reversed_content = content[::-1]

with open('reversed_content.txt', 'w') as output_file:
    output_file.write(reversed_content)

print("The content has been reversed and written to 'reversed_content.txt'.")

Soru 4: Bir dosyayı okuyup en çok kelime barındıran satırı bulan ve bu satırı ve bu satırın kaç kelimeden oluştuğunu ekrana yazdıran kodu yazınız.

Cevap

# Dosyayı aç ve oku
with open('okubeni.txt', 'r', encoding='utf-8') as file:
    satirlar = file.readlines()

en_uzun_satir = ''
max_kelime_sayisi = 0

for satir in satirlar:
    kelimeler = satir.split()  # Satırı kelimelere ayır
    kelime_sayisi = len(kelimeler)

    if kelime_sayisi > max_kelime_sayisi:
        max_kelime_sayisi = kelime_sayisi
        en_uzun_satir = satir

print(f"En uzun satır: {en_uzun_satir.strip()}")
print(f"Bu satır {max_kelime_sayisi} kelimeden oluşuyor.")

Soru 5: Bir dizindeki txt dosyalarının adlarını bir başka dosyaya yazan kodu yazınız

Cevap

import os

directory = './'  # Dizin yolu
output_file = 'dosya_isimleri.txt'

txt_dosyalari = []

for filename in os.listdir(directory):
    if filename.endswith('.txt'):
        txt_dosyalari.append(filename)

with open(output_file, 'w', encoding='utf-8') as output:
    for dosya_adi in txt_dosyalari:
        output.write(dosya_adi + '\n')

print(f"Tüm .txt dosya adları '{output_file}' dosyasına yazıldı.")