Đọc và ghi file trong Python: open(), read(), write() từ A đến Z
Khi học Python, bạn sẽ đến lúc cần lưu dữ liệu ra file hoặc đọc dữ liệu từ file. Điểm số học sinh, cấu hình ứng dụng, danh sách sản phẩm — tất cả đều cần thao tác đọc ghi file. Bài viết này hướng dẫn đầy đủ cách dùng open(), read(), write() cùng với with statement, CSV và JSON trong Python.
Tại sao cần đọc ghi file trong Python?
Biến và danh sách trong Python chỉ tồn tại trong RAM — khi tắt chương trình, dữ liệu mất hết. File giúp dữ liệu tồn tại lâu dài. Một số ứng dụng thực tế:
- Lưu danh sách học sinh và điểm số vào file
.csv - Đọc cấu hình ứng dụng từ file
.json - Ghi log lỗi vào file
.txt - Xử lý dữ liệu từ file Excel xuất ra dạng CSV
Hàm open() trong Python
Cổng vào để làm việc với file trong Python là hàm open():
open(file, mode='r', encoding=None)
Trong đó:
file: Đường dẫn đến file (ví dụ:"data.txt","C:/Users/Minh/data.txt")mode: Chế độ mở file (xem bảng bên dưới)encoding: Kiểu mã hóa ký tự — luôn dùng"utf-8"để tránh lỗi chữ tiếng Việt
Bảng các chế độ mode trong open()
| Mode | Ý nghĩa | Đọc | Ghi | Tạo mới | Ghi đè |
|---|---|---|---|---|---|
r | Đọc (mặc định) | ✓ | ✗ | ✗ | ✗ |
w | Ghi (tạo mới hoặc ghi đè) | ✗ | ✓ | ✓ | ✓ |
a | Ghi thêm vào cuối | ✗ | ✓ | ✓ | ✗ |
r+ | Đọc và ghi | ✓ | ✓ | ✗ | ✗ |
rb | Đọc dạng binary | ✓ | ✗ | ✗ | ✗ |
wb | Ghi dạng binary | ✗ | ✓ | ✓ | ✓ |
ab | Ghi thêm binary | ✗ | ✓ | ✓ | ✗ |
Lưu ý quan trọng:
- Mode
r: Nếu file không tồn tại →FileNotFoundError - Mode
w: Nếu file đã có → xóa hết nội dung cũ rồi ghi mới - Mode
a: Giữ nguyên nội dung cũ, chỉ thêm vào cuối - Mode
rb,wb: Dùng cho file ảnh, PDF, ZIP…
with open() — Cách đúng để làm việc với file
Trước khi học đọc/ghi file, bạn cần biết cách mở file an toàn bằng with statement.
Cách không nên làm
# KHÔNG NÊN — Dễ bị lỗi resource leak
f = open("data.txt", "r", encoding="utf-8")
noi_dung = f.read()
# Nếu có lỗi xảy ra ở đây, f.close() sẽ không được gọi!
f.close()
Cách đúng — Dùng with statement
# NÊN DÙNG — with tự động đóng file
with open("data.txt", "r", encoding="utf-8") as f:
noi_dung = f.read()
# File được đóng tự động khi ra khỏi block with
# Dù có exception hay không cũng đều được đóng đúng cách
Ba lợi ích của with open():
- Tự động đóng file — không cần gọi
f.close() - An toàn với exception — file được đóng ngay cả khi có lỗi
- Code gọn gàng — dễ đọc và bảo trì hơn
Mở nhiều file cùng lúc
# Đọc file này và ghi vào file kia
with open("dau_vao.txt", "r", encoding="utf-8") as fin, \
open("dau_ra.txt", "w", encoding="utf-8") as fout:
for dong in fin:
fout.write(dong.upper()) # Chuyển sang chữ hoa và ghi ra file
Đọc file trong Python: read(), readline(), readlines()
Python có 3 phương thức chính để read file, mỗi cái phù hợp với tình huống khác nhau.
read() — Đọc toàn bộ file
# Đọc toàn bộ nội dung file thành 1 string
with open("bai_tho.txt", "r", encoding="utf-8") as f:
toan_bo = f.read()
print(toan_bo)
# Output:
# Sông núi nước Nam vua Nam ở
# Tiệt nhiên định phận tại thiên thư
# Đọc N ký tự đầu tiên
with open("bai_tho.txt", "r", encoding="utf-8") as f:
doan_dau = f.read(20) # Đọc 20 ký tự đầu
print(doan_dau)
readline() — Đọc từng dòng một
with open("danh_sach.txt", "r", encoding="utf-8") as f:
dong_1 = f.readline() # Đọc dòng 1 (có chứa \n cuối dòng)
dong_2 = f.readline() # Đọc dòng 2
print(dong_1.strip()) # .strip() loại bỏ \n và khoảng trắng
print(dong_2.strip())
readlines() — Đọc tất cả các dòng vào list
with open("mon_hoc.txt", "r", encoding="utf-8") as f:
tat_ca = f.readlines()
# ['Python\n', 'JavaScript\n', 'SQL\n', 'Git\n']
for mon in tat_ca:
print(mon.strip())
Vòng lặp for — Cách Pythonic nhất
# Cách tốt nhất cho file lớn — tiết kiệm RAM
with open("nhat_ky.txt", "r", encoding="utf-8") as f:
for so_dong, dong in enumerate(f, start=1):
print(f"Dòng {so_dong}: {dong.strip()}")
So sánh các phương thức đọc file
| Phương thức | Trả về | Dùng khi nào |
|---|---|---|
read() |
string | File nhỏ, cần toàn bộ nội dung |
readline() |
string | Đọc từng dòng theo ý muốn |
readlines() |
list | Cần danh sách tất cả các dòng |
for line in f |
string | File lớn, xử lý tuần tự, tiết kiệm RAM |
Ghi file trong Python: write() và writelines()
write() — Ghi một chuỗi vào file
# Ghi thông tin học sinh ra file
with open("ket_qua.txt", "w", encoding="utf-8") as f:
f.write("=== Kết quả học tập ===\n")
f.write("Họ tên: Nguyễn Văn Minh\n")
f.write("Lớp: 12A1\n")
f.write("Điểm trung bình: 9.2\n")
f.write("Xếp loại: Xuất sắc\n")
Chú ý: write() không tự thêm \n — bạn phải tự thêm khi cần xuống dòng.
writelines() — Ghi list các chuỗi
ds_hoc_sinh = [
"1. Nguyễn Văn Minh - 9.5\n",
"2. Trần Thị Hoa - 8.0\n",
"3. Lê Văn Nam - 7.5\n",
"4. Phạm Thị Lan - 8.8\n",
]
with open("diem_lop.txt", "w", encoding="utf-8") as f:
f.writelines(ds_hoc_sinh) # Ghi tất cả phần tử của list
Mode a — Ghi thêm vào cuối file (không xóa nội dung cũ)
import datetime
# Ghi log: mỗi lần chạy, thêm 1 dòng vào cuối file
thoi_gian = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open("app.log", "a", encoding="utf-8") as f:
f.write(f"[{thoi_gian}] Ứng dụng khởi động thành công\n")
# Sau 3 lần chạy, file sẽ có 3 dòng log
Đọc ghi file CSV trong Python
CSV (Comma-Separated Values) là định dạng bảng tính phổ biến, tương thích với Excel. Python có module csv tích hợp sẵn.
Đọc file CSV
Giả sử file hoc_sinh.csv có nội dung:
ten,diem,xep_loai
Minh,9.5,Giỏi
Hoa,8.0,Khá
Nam,7.5,Khá
import csv
# Cách 1: csv.reader — trả về list
with open("hoc_sinh.csv", "r", encoding="utf-8", newline="") as f:
doc = csv.reader(f)
next(doc) # Bỏ qua dòng tiêu đề
for hang in doc:
ten, diem, xep_loai = hang
print(f"{ten}: {diem} điểm — {xep_loai}")
import csv
# Cách 2: csv.DictReader — trả về dict (tiện hơn!)
with open("hoc_sinh.csv", "r", encoding="utf-8", newline="") as f:
doc = csv.DictReader(f)
for hang in doc:
print(f"Tên: {hang['ten']}, Điểm: {hang['diem']}")
Ghi file CSV
import csv
du_lieu = [
["ten", "diem", "xep_loai"],
["Nguyễn Văn Minh", 9.5, "Giỏi"],
["Trần Thị Hoa", 8.0, "Khá"],
["Lê Văn Nam", 7.5, "Khá"],
["Phạm Thị Lan", 8.8, "Giỏi"],
]
with open("ket_qua.csv", "w", encoding="utf-8", newline="") as f:
viet = csv.writer(f)
viet.writerows(du_lieu) # Ghi tất cả các hàng
print("Đã lưu kết quả vào ket_qua.csv")
Tại sao cần newline=""? Trên Windows, nếu không có tham số này, file CSV sẽ có thêm dòng trắng thừa giữa mỗi dòng dữ liệu.
Đọc ghi file JSON trong Python
JSON là định dạng dữ liệu được dùng rộng rãi trong web API và cấu hình ứng dụng. Module json của Python giúp làm việc với JSON rất dễ dàng.
Đọc file JSON
import json
# File cau_hinh.json:
# {"ten_app": "VietCode", "phien_ban": "1.0", "tinh_nang": ["blog", "quiz"]}
with open("cau_hinh.json", "r", encoding="utf-8") as f:
cau_hinh = json.load(f) # Trả về dict Python
print(cau_hinh["ten_app"]) # VietCode
print(cau_hinh["phien_ban"]) # 1.0
print(cau_hinh["tinh_nang"][0]) # blog
Ghi file JSON
import json
nguoi_dung = {
"ten": "Nguyễn Văn Minh",
"tuoi": 22,
"ky_nang": ["Python", "SQL", "Git"],
"dia_chi": "Hà Nội",
"dang_hoc": True
}
with open("nguoi_dung.json", "w", encoding="utf-8") as f:
json.dump(nguoi_dung, f, ensure_ascii=False, indent=2)
# ensure_ascii=False → Giữ nguyên chữ tiếng Việt
# indent=2 → Xuống dòng và thụt lề cho dễ đọc
json.load vs json.loads — Phân biệt 2 hàm hay nhầm
import json
# json.load(f) — Đọc từ FILE object
with open("data.json", "r", encoding="utf-8") as f:
du_lieu = json.load(f)
# json.loads(string) — Parse từ CHUỖI (s = string)
chuoi_json = '{"ten": "Minh", "diem": 9.5}'
du_lieu = json.loads(chuoi_json)
# json.dump(obj, f) — Ghi ra FILE
with open("output.json", "w") as f:
json.dump(du_lieu, f)
# json.dumps(obj) — Chuyển thành CHUỖI JSON
chuoi = json.dumps(du_lieu, ensure_ascii=False)
print(chuoi) # '{"ten": "Minh", "diem": 9.5}'
Encoding — Xử lý lỗi chữ tiếng Việt
Đây là vấn đề thường gặp nhất khi làm việc với file tiếng Việt trong Python, đặc biệt trên Windows.
# KHÔNG NÊN — Không chỉ định encoding
with open("van_ban.txt", "r") as f:
data = f.read()
# Trên Windows: UnicodeDecodeError: 'cp1252' codec can't decode byte...
# ĐÚNG — Luôn chỉ định encoding='utf-8'
with open("van_ban.txt", "r", encoding="utf-8") as f:
data = f.read() # Chữ Việt hiển thị đúng
# Trường hợp file có BOM (Byte Order Mark) từ Excel
with open("file_excel.txt", "r", encoding="utf-8-sig") as f:
data = f.read() # utf-8-sig tự động bỏ BOM
Các lỗi thường gặp khi đọc ghi file Python
Lỗi 1: FileNotFoundError
try:
with open("data.txt", "r", encoding="utf-8") as f:
data = f.read()
print("Đọc file thành công!")
except FileNotFoundError:
print("Lỗi: Không tìm thấy file data.txt")
data = ""
except UnicodeDecodeError:
print("Lỗi: File không đúng định dạng UTF-8")
data = ""
Tìm hiểu thêm về xử lý lỗi trong Python với try/except.
Lỗi 2: Ghi đè file quan trọng bằng mode 'w'
# NGUY HIỂM — Mode w xóa hết nội dung cũ!
with open("du_lieu_quan_trong.txt", "w", encoding="utf-8") as f:
f.write("Chỉ có dòng này thôi")
# Toàn bộ dữ liệu cũ đã mất!
# ĐÚNG — Dùng mode a nếu muốn thêm vào
with open("du_lieu_quan_trong.txt", "a", encoding="utf-8") as f:
f.write("Thêm dòng mới\n")
Lỗi 3: Quên \n khi dùng write()
# SAI — Tất cả viết liền nhau
with open("output.txt", "w", encoding="utf-8") as f:
f.write("Dòng 1")
f.write("Dòng 2")
# File chứa: "Dòng 1Dòng 2"
# ĐÚNG — Thêm \n
with open("output.txt", "w", encoding="utf-8") as f:
f.write("Dòng 1\n")
f.write("Dòng 2\n")
Lỗi 4: Ghi số nguyên/float trực tiếp vào file
diem = 9.5
# SAI — write() chỉ nhận string
with open("output.txt", "w") as f:
f.write(diem) # TypeError: write() argument must be str, not float
# ĐÚNG — Chuyển sang string trước
with open("output.txt", "w", encoding="utf-8") as f:
f.write(f"Điểm: {diem}\n") # Dùng f-string
Tìm hiểu thêm về biến trong Python để hiểu rõ các kiểu dữ liệu.
Tổng hợp — Checklist làm việc với file Python
- Luôn dùng
with open()thay vì mở file thủ công - Luôn chỉ định
encoding="utf-8"để tránh lỗi chữ Việt - Chọn đúng mode:
rđọc,wghi mới,athêm vào - Dùng
try/exceptđể bắt lỗiFileNotFoundError - Dùng module
csvcho file CSV - Dùng
ensure_ascii=Falsekhi ghi JSON tiếng Việt - Nhớ thêm
\nkhi dùngwrite()