Sớm hay muộn chương trình của bạn cũng cần đọc dữ liệu từ file hoặc ghi kết quả ra đĩa. Python làm việc này khá đơn giản, nhưng có vài điểm dễ sai.
Luôn dùng with
with open("du_lieu.txt", encoding="utf-8") as f:
noi_dung = f.read()
# file tự đóng ở đây, kể cả khi có lỗi xảy ra bên trong
Đừng viết f = open(...) rồi tự gọi f.close(). Nếu có ngoại lệ xảy ra giữa chừng, file sẽ không được đóng, và trên hệ thống chạy lâu điều đó dẫn tới cạn kiệt file descriptor.
Luôn chỉ rõ encoding
Đây là lỗi phổ biến nhất với dữ liệu tiếng Việt:
with open("du_lieu.txt") as f: # thiếu encoding
...
Không có tham số này, Python dùng bảng mã mặc định của hệ điều hành — trên Linux thường là UTF-8, nhưng trên Windows có thể là cp1258 hoặc cp1252. Code chạy tốt trên máy bạn rồi lỗi trên máy khác chính là vì vậy.
with open("du_lieu.txt", encoding="utf-8") as f:
...
Các chế độ mở file
open(f, "r") # đọc (mặc định)
open(f, "w") # ghi - XÓA SẠCH nội dung cũ
open(f, "a") # ghi thêm vào cuối
open(f, "x") # tạo mới, báo lỗi nếu file đã tồn tại
open(f, "rb") # đọc nhị phân (ảnh, pdf...)
Chế độ "w" xóa toàn bộ nội dung ngay khi mở, trước cả khi bạn ghi gì. Nhầm "w" với "a" là cách mất dữ liệu rất nhanh.
Chế độ "x" hữu ích khi bạn muốn chắc chắn không ghi đè lên file có sẵn:
try:
with open("bao_cao.txt", "x", encoding="utf-8") as f:
f.write("...")
except FileExistsError:
print("File đã tồn tại, không ghi đè")
Đọc file lớn
f.read() nạp toàn bộ file vào bộ nhớ. Với file vài gigabyte, chương trình sẽ hết RAM. Hãy duyệt từng dòng:
with open("nhat_ky.log", encoding="utf-8") as f:
for dong in f: # chỉ giữ một dòng tại một thời điểm
if "ERROR" in dong:
print(dong.rstrip())
Cách này đọc được file lớn hơn RAM nhiều lần.
Ghi file
ket_qua = ["dòng 1", "dòng 2", "dòng 3"]
with open("ket_qua.txt", "w", encoding="utf-8") as f:
for dong in ket_qua:
f.write(dong + "\n")
# hoặc
f.writelines(d + "\n" for d in ket_qua)
Chú ý write không tự thêm dấu xuống dòng — khác với print.
pathlib: cách hiện đại để làm việc với đường dẫn
from pathlib import Path
thu_muc = Path("du_lieu")
tep = thu_muc / "bao_cao.csv" # tự dùng đúng dấu phân cách của hệ điều hành
print(tep.exists())
print(tep.suffix) # .csv
print(tep.stem) # bao_cao
print(tep.parent) # du_lieu
# Đọc ghi nhanh, không cần with
noi_dung = tep.read_text(encoding="utf-8")
tep.write_text("nội dung mới", encoding="utf-8")
# Tạo thư mục
Path("ket_qua/2026").mkdir(parents=True, exist_ok=True)
# Duyệt file
for f in Path("du_lieu").glob("*.csv"):
print(f.name)
for f in Path("du_lieu").rglob("*.py"): # kể cả thư mục con
print(f)
Toán tử / để nối đường dẫn tránh được lỗi kinh điển của việc ghép chuỗi thủ công, và code chạy đúng trên cả Windows lẫn Linux.
Làm việc với CSV
import csv
# Đọc
with open("nhan_vien.csv", encoding="utf-8-sig", newline="") as f:
for hang in csv.DictReader(f):
print(hang["ho_ten"], hang["phong_ban"])
# Ghi
with open("ket_qua.csv", "w", encoding="utf-8-sig", newline="") as f:
ghi = csv.DictWriter(f, fieldnames=["ho_ten", "diem"])
ghi.writeheader()
ghi.writerow({"ho_ten": "An", "diem": 8.5})
Hai chi tiết quan trọng: newline="" ngăn dòng trống xen kẽ trên Windows, còn utf-8-sig giúp Excel mở file hiển thị đúng tiếng Việt.
Làm việc với JSON
import json
du_lieu = {"ten": "Minh", "diem": [8, 9, 7]}
# Ghi
with open("du_lieu.json", "w", encoding="utf-8") as f:
json.dump(du_lieu, f, ensure_ascii=False, indent=2)
# Đọc
with open("du_lieu.json", encoding="utf-8") as f:
du_lieu = json.load(f)
Tham số ensure_ascii=False rất quan trọng với tiếng Việt. Thiếu nó, file JSON sẽ đầy những chuỗi kiểu ế — vẫn đọc lại được nhưng con người không xem nổi.
Ghi file an toàn
Nếu chương trình bị ngắt giữa lúc ghi, bạn sẽ có một file hỏng dở dang. Cách tránh: ghi ra file tạm rồi đổi tên:
from pathlib import Path
import os
def ghi_an_toan(duong_dan, noi_dung):
dich = Path(duong_dan)
tam = dich.with_suffix(dich.suffix + ".tmp")
tam.write_text(noi_dung, encoding="utf-8")
os.replace(tam, dich) # thao tác nguyên tử trên cùng ổ đĩa
os.replace đảm bảo file đích hoặc là bản cũ nguyên vẹn, hoặc là bản mới hoàn chỉnh — không bao giờ ở trạng thái nửa vời.