Kursus Python / Membaca dan menulis berkas teks dengan with dan encoding

Buka berkas teks dengan encoding yang ditentukan dan gunakan with untuk menutupnya saat blok selesai. Mode w memotong isi berkas yang sudah ada, sehingga penulisan keluaran baru harus dibedakan dari penggantian data yang perlu dipertahankan.

Pilih mode dan encoding sesuai tujuan

Mode Tujuan Perilaku terhadap berkas
r Membaca Gagal jika berkas tidak ada
w Menulis pengganti Membuat jika belum ada; memotong isi jika sudah ada
a Menambahkan pada akhir Membuat jika belum ada
x Membuat berkas baru saja Gagal jika target sudah ada

Encoding mengatur cara karakter direpresentasikan sebagai byte. Untuk data UTF-8, tulis encoding="utf-8" secara eksplisit agar maksudnya jelas dan tidak bergantung pada nilai bawaan lingkungan. Memilih encoding harus sesuai dengan data sumber, bukan sekadar memilih nama encoding yang membuat kesalahan hilang.

errors="ignore" dapat membuang bagian yang gagal didekode, sehingga bukan solusi umum untuk data yang tidak terbaca. Ketika data harus dipertahankan, cari encoding sumber atau perbaiki proses pembuatannya. Dasar penggunaannya dijelaskan pada tutorial pembacaan dan penulisan berkas Python.

Tulis, tambahkan, dan baca berkas lengkap

Gunakan folder latihan khusus yang boleh berisi data percobaan. Setiap eksekusi berikut menginisialisasi ulang notes-demo.txt dengan mode w, sehingga isi lama pada target tersebut diganti. Periksa folder kerja sebelum menjalankannya; panduan pathlib dan lokasi berkas menjelaskan basis path relatif.

Simpan kode lengkap sebagai text_files.py dengan encoding UTF-8. Gunakan Python 3.12 atau lebih baru dalam lingkungan proyek, lalu jalankan python text_files.py. Program tidak memerlukan paket tambahan.

from pathlib import Path

path = Path("notes-demo.txt")
with path.open("w", encoding="utf-8", newline="\n") as f:
    f.write("coffee:3500\n")
    f.write("lunch:8000\n")
with path.open("a", encoding="utf-8") as f:
    f.write("bus:2500\n")
with path.open("r", encoding="utf-8") as f:
    for line in f:
        print(line.rstrip("\n"))

Keluaran yang diharapkan:

coffee:3500
lunch:8000
bus:2500

Blok pertama menulis dua baris baru. Blok kedua membuka lagi berkas dengan mode tambahan, sehingga baris bus berada setelah makan siang. Blok ketiga membacanya dari awal dan mencetak setiap baris. rstrip("\n") menghilangkan karakter newline pada akhir string sebelum print menambahkan newline tampilannya sendiri.

Opsi newline="\n" pada penulisan pertama tidak menerjemahkan newline ke pemisah lain. Blok tambahan memakai pengaturan newline bawaan, sehingga byte pemisah baris dapat berbeda pada Windows walaupun pembacaan teks biasa menghasilkan tiga baris yang sama. Jangan menyamakan kesamaan tampilan dengan kesamaan byte pada semua sistem operasi.

Kelola pembacaan, posisi, dan spasi

read() membaca sisa isi sebagai string, sedangkan for line in f memproses satu baris pada satu waktu. Jika tidak perlu seluruh isi sekaligus, iterasi per baris menghindari pemuatan seluruh berkas ke memori. Satu baris yang sangat besar tetap memerlukan memori untuk baris tersebut.

Objek berkas menyimpan posisi baca. Setelah iterasi mencapai akhir, read() langsung menghasilkan string kosong. Buka ulang berkas atau pindahkan posisi dengan sengaja, misalnya f.seek(0) untuk kembali ke awal. String kosong setelah pembacaan bukan bukti berkas tidak pernah mempunyai isi.

strip() menghapus whitespace di kedua ujung, termasuk spasi yang mungkin menjadi bagian data. Gunakan penghapusan terbatas seperti rstrip("\n") jika hanya newline yang hendak dibuang. Pada pembacaan teks dengan newline bawaan, pemisah seperti CRLF dapat diterjemahkan menjadi \n; dengan pengaturan lain, karakter yang tersisa dapat berbeda. Untuk pemrosesan data yang menuntut pemisah asli, tentukan newline sesuai kebutuhan.

with memastikan penutupan ketika keluar normal maupun ketika pengecualian meninggalkan blok, asalkan berkas berhasil dibuka. Ia tidak membuat penulisan menjadi transaksi. Jika berkas dibuka dengan w lalu terjadi kesalahan sebelum data baru selesai ditulis, isi lama dapat sudah hilang.

Lindungi data asal dan telusuri kegagalan

Untuk data penting, simpan cadangan dan pertimbangkan menulis ke berkas sementara terpisah, memvalidasi hasil, lalu mengganti target sesuai kebijakan aplikasi. Penutupan berkas saja tidak menjamin ketahanan terhadap semua kegagalan disk atau pemulihan versi lama. Jika maksudnya hanya membuat berkas baru, mode x membantu menolak target yang sudah ada.

  • FileNotFoundError: periksa path yang telah diresolusikan, folder kerja, dan keberadaan direktori induk.
  • UnicodeDecodeError: periksa encoding sebenarnya dan apakah data memang teks. Jangan menganggap semua byte dapat dibaca sebagai UTF-8.
  • PermissionError: periksa izin akses, target yang ternyata direktori, dan kemungkinan penguncian oleh aplikasi lain. Pesan tepatnya bergantung pada sistem operasi dan operasi yang gagal.

Menangkap semua kesalahan lalu mengembalikan string kosong menghilangkan perbedaan antara berkas yang hilang, berkas kosong, dan data rusak. Tangani pengecualian hanya ketika program mempunyai kebijakan pemulihan yang jelas.

  1. Jalankan versi asli dua kali. Hasil tetap tiga baris karena pembukaan pertama mengganti isi lama.
  2. Ganti hanya mode w pertama menjadi a, lalu jalankan lagi. Tiga catatan baru ditambahkan ke catatan sebelumnya, sehingga data berulang.
  3. Pulihkan w dan jalankan kembali untuk mengembalikan tiga baris contoh. Lakukan percobaan hanya pada berkas latihan yang telah ditentukan.

Periksa hasil tampilan dan isi berkas secara terpisah. Program yang tidak menampilkan kesalahan masih dapat menulis ke folder yang salah atau menambahkan catatan ganda jika pilihan path dan mode tidak sesuai tujuan.