Bab 9: Membaca & Menulis File¶
Program yang tidak menyentuh file = program yang lupa segala-galanya begitu ditutup. File = memori jangka panjang.
Sampai sekarang, semua data program kita hilang begitu program ditutup. Itu kalau cuma latihan oke, tapi untuk program nyata kamu butuh persistensi — data tersimpan di disk dan bisa dibaca lagi besok.
Setelah Bab 9, kamu akan bisa:
- Bekerja dengan path file (Windows, Mac, Linux)
- Buka, baca, tulis, append file teks
- Pakai
pathlib(cara modern) danos.path(cara klasik) - Backup, copy, delete file
- Bekerja dengan file zip
- Pakai shelve untuk simpan dictionary Python ke disk
9.1. Path File — Lokasi File di Disk¶
Sebelum bisa baca/tulis file, kamu harus bisa menunjukkan lokasi-nya ke Python.
Path Absolut vs Relatif¶
- Absolut: lokasi lengkap dari root disk.
C:\Users\yazid\Documents\nota.txtdi Windows,/home/yazid/Documents/nota.txtdi Linux. - Relatif: dari direktori kerja saat ini.
Documents\nota.txt(artinya: dari folder saat ini, masuk ke Documents, ambil nota.txt).
Hati-hati dengan Backslash di Windows¶
Windows pakai \ sebagai separator. Tapi \ di Python adalah escape character. Jadi:
# SALAH — Python interpret \U, \n sebagai escape
path = "C:\Users\nama\nota.txt"
# BENAR — pakai raw string
path = r"C:\Users\nama\nota.txt"
# BENAR — atau forward slash, Python paham
path = "C:/Users/nama/nota.txt"
# PALING BENAR — pakai pathlib (cross-platform)
from pathlib import Path
path = Path("C:/Users/nama/nota.txt")
9.2. pathlib — Cara Modern (Direkomendasikan)¶
from pathlib import Path
# Path saat ini (current working directory)
print(Path.cwd())
# Home directory
print(Path.home())
# Build path dengan / (operator overload yang elegan)
path = Path.home() / "Documents" / "nota.txt"
print(path)
# Cek file/folder
print(path.exists())
print(path.is_file())
print(path.is_dir())
# Properti file
print(path.name) # 'nota.txt'
print(path.stem) # 'nota'
print(path.suffix) # '.txt'
print(path.parent) # path folder parent
flowchart LR
Path["Path('C:/Users/yazid/Documents/nota.txt')"]
Path -- ".name" --> Name["'nota.txt'"]
Path -- ".stem" --> Stem["'nota'"]
Path -- ".suffix" --> Suffix["'.txt'"]
Path -- ".parent" --> Parent["Path('C:/Users/yazid/Documents')"]
style Path fill:#1a1a1a,stroke:#6366f1,color:#fafafa
style Name fill:#1a1a1a,stroke:#10b981,color:#fafafa
style Stem fill:#1a1a1a,stroke:#10b981,color:#fafafa
style Suffix fill:#1a1a1a,stroke:#10b981,color:#fafafa
style Parent fill:#1a1a1a,stroke:#f59e0b,color:#fafafa
Cara baca diagram
Diagram ini menunjukkan anatomi Path object dan property-nya.
Untuk path C:/Users/yazid/Documents/nota.txt:
.name= nama file lengkap dengan ekstensi ('nota.txt').stem= nama file tanpa ekstensi ('nota').suffix= ekstensi termasuk titik ('.txt').parent= folder yang berisi file (Pathobject lagi)
Kunci: Path object berbeda dari string biasa. Dia "tahu" bahwa dirinya adalah path file, jadi punya method-method spesifik untuk path manipulation.
Trik praktis: ganti ekstensi file dengan .with_suffix():
Berguna untuk batch convert file.
List File di Folder¶
folder = Path.home() / "Documents"
# Semua file & folder
for item in folder.iterdir():
print(item)
# Hanya file .txt
for txt in folder.glob("*.txt"):
print(txt)
# Recursive — cari di subfolder juga
for txt in folder.rglob("*.txt"):
print(txt)
9.3. Baca File Teks¶
Cara Sederhana — read_text()¶
Cara Klasik — open() + with¶
with menjamin file ditutup otomatis setelah selesai — bahkan kalau ada error.
Mode Open¶
| Mode | Arti |
|---|---|
"r" |
Read (baca, default) |
"w" |
Write — overwrite isi |
"a" |
Append — tambah di akhir |
"x" |
Create exclusive — error kalau sudah ada |
"b" |
Binary mode (gabungkan: "rb", "wb") |
Baca Per Baris¶
with open("nota.txt", "r", encoding="utf-8") as f:
for baris in f:
print(baris.rstrip()) # rstrip() hapus \n di akhir
Atau dapat list semua baris:
9.4. Tulis File Teks¶
Cara Sederhana¶
Cara Klasik¶
Append (Tambah di Akhir)¶
Mode w MENGHAPUS isi file lama!
Selalu cek mode dengan teliti. Mode w membuat file baru atau mengganti seluruh isi file lama.
Kalau kamu mau preserve isi, pakai a (append) atau baca-modifikasi-tulis.
9.5. Operasi File dengan shutil¶
shutil (shell utility) untuk operasi file dan folder:
import shutil
from pathlib import Path
# Copy file
shutil.copy("src.txt", "tujuan.txt")
# Copy folder beserta isinya
shutil.copytree("src_folder", "tujuan_folder")
# Pindah / rename
shutil.move("lama.txt", "baru.txt")
# Hapus file
Path("file.txt").unlink()
# Hapus folder beserta isinya
shutil.rmtree("folder_to_delete")
Operasi destruktif tidak bisa di-undo
unlink() dan rmtree() menghapus permanen, tidak masuk Recycle Bin. Untuk hapus yang aman (masuk recycle bin), pakai library send2trash:
9.6. Walking Direktori¶
Untuk proses semua file dalam folder beserta subfolder, pakai os.walk:
import os
for folder_skrg, subfolder_list, file_list in os.walk("c:/Users/nama/Documents"):
print(f"Folder: {folder_skrg}")
for sub in subfolder_list:
print(f" Subfolder: {sub}")
for file in file_list:
print(f" File: {file}")
Atau pakai pathlib:
9.7. File Zip¶
import zipfile
# Buat zip
with zipfile.ZipFile("backup.zip", "w") as z:
z.write("file1.txt")
z.write("file2.txt")
z.write("folder/file3.txt")
# Baca zip
with zipfile.ZipFile("backup.zip") as z:
print(z.namelist()) # daftar file di dalam
z.extractall("extracted/") # ekstrak semua
9.8. shelve — Simpan Dictionary ke File¶
Untuk simpan/baca dictionary Python ke disk dengan mudah:
import shelve
with shelve.open("data.shelf") as db:
db["users"] = ["Andi", "Sari", "Budi"]
db["config"] = {"theme": "dark", "lang": "id"}
# Baca lagi nanti
with shelve.open("data.shelf") as db:
print(db["users"])
print(db["config"]["theme"])
Cocok untuk simple persistent storage. Untuk yang serius, pakai SQLite atau JSON (Bab 16).
9.9. Project: Backup Otomatis¶
import shutil
from pathlib import Path
from datetime import datetime
def backup_folder(src, dest):
"""Backup folder dengan timestamp."""
src = Path(src)
dest = Path(dest)
if not src.is_dir():
print(f"⚠ Source bukan folder valid: {src}")
return
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
nama_backup = f"{src.name}_backup_{timestamp}"
target = dest / nama_backup
print(f"Backup {src} → {target}")
shutil.copytree(src, target)
print(f"✓ Selesai. Total file:")
total = 0
for item in target.rglob("*"):
if item.is_file():
total += 1
print(f" {total} file di-backup")
backup_folder(
src=Path.home() / "Documents" / "Project",
dest=Path.home() / "Backups",
)
9.10. Ringkasan¶
pathlib.Path= cara modern, cross-platform untuk pathPath.cwd(),Path.home()= direktori penting/operator untuk gabung path.exists(),.is_file(),.is_dir()untuk cek.read_text(),.write_text()= baca/tulis cepatwith open(...) as f:= cara klasik, lebih kontrol- Mode:
r(baca),w(overwrite),a(append) shutiluntuk copy/move/deleteos.walk/Path.rglobuntuk iterasi folderzipfileuntuk operasi zipshelveuntuk persist dictionary
9.11. Latihan¶
9.1 — Word Count¶
Baca file teks, hitung jumlah kata, baris, dan karakter.
9.2 — Find & Replace¶
Buat fungsi replace_in_file(file, lama, baru) yang ganti semua occurrence di file.
9.3 — Pencarian Teks¶
Cari semua file .txt di folder dan subfolder yang mengandung kata tertentu.
9.4 — Konsolidasi¶
Gabung semua file .txt di folder jadi satu file gabungan.txt.
9.5 — Backup Tantangan¶
Modifikasi project backup di atas: hanya backup file yang dimodifikasi dalam 7 hari terakhir.
Path (Modern)¶
from pathlib import Path
Path.cwd() # current dir
Path.home() # home folder
Path("a") / "b" / "c.txt" # build path
p = Path("file.txt")
p.exists() p.is_file() p.is_dir()
p.name # 'file.txt'
p.stem # 'file'
p.suffix # '.txt'
p.parent # parent folder
p.with_suffix(".pdf")
List Files¶
folder.iterdir() # immediate children
folder.glob("*.txt") # filter ekstensi
folder.rglob("*.txt") # recursive
Baca/Tulis Cepat¶
Path("file.txt").read_text(encoding="utf-8")
Path("file.txt").write_text(content, encoding="utf-8")
Path("file.bin").read_bytes()
Path("file.bin").write_bytes(data)
Mode open()¶
| Mode | Arti |
|---|---|
r |
baca (default) |
w |
tulis (OVERWRITE!) |
a |
append (tambah di akhir) |
x |
buat baru, error kalau ada |
b |
binary (gabung: rb, wb) |
Pola Standard¶
shutil¶
shutil.copy(src, dst)
shutil.copytree(src, dst)
shutil.move(src, dst)
shutil.rmtree(folder) # hapus folder beserta isi
Hapus¶
Path("file.txt").unlink()
shutil.rmtree("folder")
# Untuk safe (recycle bin):
import send2trash
send2trash.send2trash("file")
Zip¶
import zipfile
with zipfile.ZipFile("a.zip", "w") as z:
z.write("file.txt")
with zipfile.ZipFile("a.zip") as z:
z.namelist()
z.extractall("dest/")