File I/O (Input/Output) adalah cara program membaca data dari berkas dan menulis hasilnya kembali ke penyimpanan. Hampir semua alur kerja pengembangan atau penggunaan program, mulai dari analisis data sampai otomasi, membutuhkan File I/O yang rapi, aman, dan efisien.
/home/user/data.txt di Linux/macOS; C:\Users\... di Windows).data.txt, ./data/data.txt).Metode yang biasa digunakan → open(path, mode, ...):
'r': baca (gagal jika file tidak ada)'w': tulis baru (menghapus isi lama)'a': append (tambah di akhir)'x': buat baru (gagal jika sudah ada)'b' untuk biner (mis. 'rb', 'wb'), 't' untuk teks (default)'+' untuk baca+tulis (mis. 'r+')encoding.with)Selalu gunakan context manager agar file tertutup otomatis, bahkan jika terjadi error.
# Membaca file teks
with open("catatan.txt", mode="r", encoding="utf-8") as f:
isi = f.read()
print(isi) # file sudah tertutup di sini
Mengapa with?
f = open(...); ...; f.close().with open("puisi.txt", "r", encoding="utf-8") as f:
teks = f.read() # return str
Cocok untuk file kecil/menengah. Untuk file besar, baca bertahap.
with open("log.txt", "r", encoding="utf-8") as f:
for baris in f: # iterator baris demi baris
proses(baris.rstrip("\n"))
readline() & readlines()with open("data.txt", "r", encoding="utf-8") as f:
satu_baris = f.readline() # baca satu baris
semua_baris = f.readlines() # list[str] -> hati-hati memori
CHUNK = 1024 * 1024 # 1 MB
with open("besar.txt", "r", encoding="utf-8") as f:
while True:
potong = f.read(CHUNK)
if not potong:
break
proses(potong)
with open("keluaran.txt", "w", encoding="utf-8") as f:
f.write("Halo dunia!\n")
f.writelines(["Baris 1\n", "Baris 2\n"])
with open("log.txt", "a", encoding="utf-8") as f:
f.write("[INFO] program dijalankan\n")
f.flush() untuk paksa tulis, atau buka dengan buffering=1 (line-buffered) untuk streaming log.print(..., flush=True).CHUNK = 1024 * 64
with open("gambar.png", "rb") as src, open("salinan.png", "wb") as dst:
while True:
blok = src.read(CHUNK)
if not blok: break
dst.write(blok)
bytes / bytearraywith open("model.bin", "rb") as f:
data = f.read() # type: bytes
# data[0:4], len(data), dll.
Catatan: untuk struktur biner berformat, gunakan modul
struct(pack/unpack).
Selalu eksplisit encoding="utf-8" untuk portabilitas.
Jika file berisi karakter “aneh”, tangani kesalahan:
with open("teks_lokal.txt", "r", encoding="utf-8", errors="replace") as f:
teks = f.read() # karakter rusak diganti �
Opsi errors: "strict" (default), "ignore", "replace".
\n, Windows: \r\n.newline="\n" ketika menulis.with open("hasil.txt", "w", encoding="utf-8", newline="\n") as f:
f.write("baris1\nbaris2\n")
pathlib: Cara Modern Kelola Pathpathlib lebih bersih daripada os.path—object oriented & portabel.
from pathlib import Path
p = Path("data") / "masukan.txt"
if p.exists():
teks = p.read_text(encoding="utf-8")
else:
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text("awal\n", encoding="utf-8")
Operasi umum:
for file in Path("logs").glob("*.log"):
print(file.name, file.stat().st_size, "bytes")
Path("old.txt").rename("arsip/old.txt")
Path("sementara.txt").unlink(missing_ok=True)
csv & DictReader/DictWriterimport csv
from pathlib import Path
# tulis
with Path("nilai.csv").open("w", encoding="utf-8", newline="") as f:
w = csv.DictWriter(f, fieldnames=["nama","nilai"])
w.writeheader()
w.writerow({"nama":"Andi", "nilai":88})
w.writerow({"nama":"Budi", "nilai":92})
# baca
with Path("nilai.csv").open("r", encoding="utf-8", newline="") as f:
r = csv.DictReader(f)
for row in r:
print(row["nama"], row["nilai"])
Gunakan
newline=""saat bekerja dengan CSV untuk mencegah baris kosong ganda di Windows.
json.load/json.dumpimport json
from pathlib import Path
data = {"versi": 1, "items": [{"id": 1, "nama": "A"}]}
Path("data.json").write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
with Path("data.json").open("r", encoding="utf-8") as f:
obj = json.load(f) # dict
Hindari
pickleuntuk pertukaran data antar-sistem (alasan keamanan & portabilitas).picklehanya untuk objek tepercaya di lingkungan Anda sendiri.
Tangkap kesalahan yang wajar—berikan pesan yang membantu pengguna:
from pathlib import Path
def baca_aman(path: Path) -> str:
try:
return path.read_text(encoding="utf-8")
except FileNotFoundError:
return f"File tidak ditemukan: {path}"
except PermissionError:
return f"Tidak punya izin untuk membaca: {path}"
except UnicodeDecodeError as e:
return f"Gagal decode UTF-8: {e}"
Daftar exception umum:
FileNotFoundErrorPermissionErrorIsADirectoryError / NotADirectoryErrorUnicodeDecodeErrorOSError (induk bagi banyak I/O error)from pathlib import Path
root = Path("arsip")
# buat folder
root.mkdir(parents=True, exist_ok=True)
# daftar isi
for p in root.iterdir():
print(p.name, "DIR" if p.is_dir() else "FILE")
# hapus file
(target := root / "lama.txt").unlink(missing_ok=True)
# pindah/rename
(Path("laporan.txt")).replace(root / "laporan_2025.txt")
with saat buka file.encoding="utf-8" untuk file teks.../../ keluar folder kerja).Tulis atomik untuk file penting: tulis ke file sementara lalu rename (operasi rename biasanya atomik).
from pathlib import Path
import os, tempfile
def atomic_write(target: Path, content: str, encoding="utf-8"):
tmp_dir = target.parent
with tempfile.NamedTemporaryFile("w", encoding=encoding, dir=tmp_dir, delete=False) as tmp:
tmp.write(content)
tmp_name = tmp.name
os.replace(tmp_name, target) # atomik di banyak FS
newline= yang benar (kosong untuk CSV, \n untuk kontrol eksplisit).logging ketimbang menulis log manual bila proyek makin besar.pickle data tak tepercaya (rawan eksekusi kode).pathlib untuk portabilitas dan kode yang bersih.Ringkasan cepat
with open(...): ...encoding="utf-8"; Biner → 'rb'/'wb' tanpa encodingcsv.DictReader/Writer (+ newline="")json.load/dump (hindari pickle untuk data publik)pathlib.Pathos.replaceCheat Sheet
# baca seluruh teks
Path("a.txt").read_text(encoding="utf-8")
# tulis teks (overwrite)
Path("a.txt").write_text("halo\n", encoding="utf-8", newline="\n")
# iterasi baris
with open("a.txt","r",encoding="utf-8") as f:
for line in f:
...
# copy biner (chunk)
with open("in.bin","rb") as s, open("out.bin","wb") as d:
while buf := s.read(65536):
d.write(buf)
# CSV
with open("x.csv","r",encoding="utf-8",newline="") as f:
r = csv.DictReader(f)
for row in r: ...
# JSON
obj = json.loads(Path("x.json").read_text(encoding="utf-8"))
Path("y.json").write_text(json.dumps(obj, ensure_ascii=False, indent=2), encoding="utf-8")
# pathlib util
p = Path("data") / "file.txt"
p.parent.mkdir(parents=True, exist_ok=True)
p.exists(), p.is_file(), p.stat().st_size