Xem thêm

Đọc ghi file trong Python: Cách chi tiết và dễ hiểu

Huy Erick
Python là một ngôn ngữ lập trình mạnh mẽ, và quá trình đọc ghi file là một phần quan trọng trong quá trình làm việc với nhiều dự án. Trong bài viết này, chúng ta...

Đọc ghi file trong Python

Python là một ngôn ngữ lập trình mạnh mẽ, và quá trình đọc ghi file là một phần quan trọng trong quá trình làm việc với nhiều dự án. Trong bài viết này, chúng ta sẽ tìm hiểu cách đọc file và ghi file trong Python, cũng như cách làm việc với file JSON.

Đọc ghi file trong Python

Quá trình đọc ghi file trong Python bao gồm 3 bước chính: Mở file, Đọc hoặc ghi file, và cuối cùng là đóng file. Chúng ta sẽ xem xét các mode khi làm việc với file trong Python trước tiên.

Mode truy cập tệp trong Python

Quá trình đọc ghi file trong Python cũng sử dụng các mode tương ứng với việc làm việc với file trong ngôn ngữ khác.

  • Read Only ('r'): Mode mặc định khi mở file. Ở chế độ này, file chỉ được phép đọc dữ liệu và con trỏ file bắt đầu ở đầu file. Nếu file không tồn tại, sẽ gặp lỗi FileNotFoundError.

  • Read & Write ('r+'): Mở file cho phép đọc và ghi. Con trỏ file ở đầu file. Nếu file không tồn tại, sẽ gặp lỗi FileNotFoundError.

  • Write Only ('w'): Mở file cho phép ghi. Con trỏ file ở đầu file. Nếu file không tồn tại, sẽ tự động tạo mới. Nếu file đã tồn tại, dữ liệu cũ sẽ bị ghi đè bằng dữ liệu mới.

  • Write & Read ('w+'): Mở file cho phép đọc và ghi. Con trỏ file ở đầu file. Nếu file không tồn tại, sẽ tự động tạo mới. Nếu file đã tồn tại, dữ liệu cũ sẽ bị ghi đè bằng dữ liệu mới.

  • Append Only ('a'): Mở file cho phép ghi. File sẽ được tạo mới nếu chưa tồn tại. Con trỏ file ở cuối file, nên việc ghi dữ liệu sẽ thêm vào cuối file nếu đã có dữ liệu ban đầu.

  • Append & Read ('a+'): Mở file cho phép đọc và ghi. File sẽ được tạo mới nếu chưa tồn tại. Con trỏ file ở cuối file, nên việc ghi dữ liệu sẽ thêm vào cuối file nếu đã có dữ liệu ban đầu.

Mở file trong Python

Để mở file trong Python, chúng ta sử dụng hàm open() có sẵn trong Python như sau:

file_object = open(r'đường_dẫn_tới_file', 'mode')

Lưu ý: Ký tự r trước đường dẫn tới file giúp bỏ qua các ký tự đặc biệt trong string trong Python. Ví dụ: nếu không có ký tự r, đường dẫn D:\text\myfile.txt này sẽ bị coi là dấu tab, dẫn tới xảy ra lỗi không mong muốn.

Ví dụ:

# Mở file để đọc, mode = 'r'
rf = open('data.txt', 'r')

# Hoặc
rf = open('data.txt')

# Mở file để ghi
wf = open('data.txt', 'w')

# Mở file để ghi vào cuối
wf = open('data.txt', 'a')

Đóng file trong Python

Sau khi đã hoàn thành công việc với file, chúng ta nên sử dụng hàm close() để đóng file. Điều này giúp ngăn ngừa các vấn đề không mong muốn xảy ra.

Ví dụ:

# Mở file để đọc, mode = 'r'
rf = open('data.txt', 'r')

# Đóng file
rf.close()

# Mở file để ghi
wf = open('data.txt', 'w')

# Đóng file
wf.close()

# Mở file để ghi vào cuối
wf = open('data.txt', 'a')

# Đóng file
wf.close()

Một cách linh hoạt hơn khi làm việc với file mà không cần phải lo khi nào đóng file là sử dụng từ khóa with như sau:

# Python sẽ tự động đóng file cho bạn
with open('/home/user/data.txt', 'r') as fp:
    # doing smt
    # tiếp tục các khối lệnh khác ...

Đọc file trong Python

Python cung cấp 3 cách khác nhau để đọc nội dung từ file. Chúng ta sẽ đi trực tiếp vào ví dụ để bạn có thể hiểu và áp dụng ngay.

Đọc toàn bộ file ra string

Sử dụng hàm read() để đọc toàn bộ nội dung file vào một biến string.

with open('data.txt') as rf:
    content = rf.read()
    print(content)

    content = content + "\nFrom LTKK with love"
    print(content)

Kết quả nhận được (cũng chính là nội dung file data.txt):

Kích thước cố định
Cần chỉ rõ kích thước trong khi khai báo
Kích thước thay đổi trong quá trình thêm/ xóa phần tử
Kích thước tối đa phụ thuộc vào bộ nhớ
typedef được dùng để định nghĩa một kiểu dữ liệu trong C.
malloc là hàm cấp phát bộ nhớ của C. Với C++ chúng ta dùng new
sizeof là hàm trả về kích thước của kiểu dữ liệu, dùng làm tham số cho hàm malloc
From LTKK with love

Đọc từng dòng của file

Sử dụng hàm readline() để trả về một dòng nội dung của file. Chúng ta có thể duyệt qua từng dòng nội dung của file như sau:

with open('data.txt') as rf:
    line = rf.readline()
    index = 1
    while line:
        print('Line {}: {}'.format(index, line))
        index += 1
        line = rf.readline()

Kết quả:

Line 1: Kích thước cố định
Line 2: Cần chỉ rõ kích thước trong khi khai báo
Line 3: Kích thước thay đổi trong quá trình thêm/ xóa phần tử
Line 4: Kích thước tối đa phụ thuộc vào bộ nhớ
Line 5: typedef được dùng để định nghĩa một kiểu dữ liệu trong C.
Line 6: malloc là hàm cấp phát bộ nhớ của C. Với C++ chúng ta dùng new
Line 7: sizeof là hàm trả về kích thước của kiểu dữ liệu, dùng làm tham số cho hàm malloc

Hàm `readline()` sẽ đọc một dòng, bao gồm cả ký tự newline (`\n`). Nên khi in ra, mỗi dòng có thể có một dòng trống ở phía dưới như kết quả ở trên.

Đọc toàn bộ file ra list

Vẫn là đọc toàn bộ file, nhưng hàm readlines() sẽ trả về một list, trong đó mỗi dòng dữ liệu là một phần tử của list.

with open('data.txt') as rf:
    lines = rf.readlines()
    for idx, line in enumerate(lines):
        print(idx, line)

Kết quả:

0 Kích thước cố định
1 Cần chỉ rõ kích thước trong khi khai báo
2 Kích thước thay đổi trong quá trình thêm/ xóa phần tử
3 Kích thước tối đa phụ thuộc vào bộ nhớ
4 typedef được dùng để định nghĩa một kiểu dữ liệu trong C.
5 malloc là hàm cấp phát bộ nhớ của C. Với C++ chúng ta dùng new
6 sizeof là hàm trả về kích thước của kiểu dữ liệu, dùng làm tham số cho hàm malloc

Lưu ý: Bạn có thể dùng hàm `strip()` để xóa khoảng trắng thừa ở đầu & cuối string. Và ký tự newline ở cuối mỗi string cũng được coi là một khoảng trắng thừa.

Ghi file trong Python

Để ghi file trong Python, chúng ta có thể sử dụng hàm write() để ghi một biến string, hoặc dùng writelines() để ghi một list các chuỗi string.

texts = [
    "0 Kích thước cố định",
    "1 Cần chỉ rõ kích thước trong khi khai báo",
    "2 Kích thước thay đổi trong quá trình thêm/ xóa phần tử",
    "3 Kích thước tối đa phụ thuộc vào bộ nhớ",
    "4 typedef được dùng để định nghĩa một kiểu dữ liệu trong C.",
    "5 malloc là hàm cấp phát bộ nhớ của C. Với C++ chúng ta dùng new",
    "6 sizeof là hàm trả về kích thước của kiểu dữ liệu, dùng làm tham số cho hàm malloc"
]

with open('data.txt', 'w') as wf:
    for text in texts:
        wf.write(text + '\n')

Hoặc:

texts = [
    "0 Kích thước cố định",
    "1 Cần chỉ rõ kích thước trong khi khai báo",
    "2 Kích thước thay đổi trong quá trình thêm/ xóa phần tử",
    "3 Kích thước tối đa phụ thuộc vào bộ nhớ",
    "4 typedef được dùng để định nghĩa một kiểu dữ liệu trong C.",
    "5 malloc là hàm cấp phát bộ nhớ của C. Với C++ chúng ta dùng new",
    "6 sizeof là hàm trả về kích thước của kiểu dữ liệu, dùng làm tham số cho hàm malloc"
]

with open('data.txt', 'w') as wf:
    wf.writelines(texts)

Hàm writelines() không tự động chèn thêm '\n' vào cuối mỗi dòng. Nên nếu chạy code trên, các dòng sẽ được ghi liền nhau thành một dòng duy nhất.

Ghi dữ liệu vào cuối file

Chúng ta chỉ cần đổi mode từ 'w' sang 'a' là được. Xem ví dụ:

texts = [
    "0 Kích thước cố định",
    "1 Cần chỉ rõ kích thước trong khi khai báo",
    "2 Kích thước thay đổi trong quá trình thêm/ xóa phần tử",
    "3 Kích thước tối đa phụ thuộc vào bộ nhớ",
    "4 typedef được dùng để định nghĩa một kiểu dữ liệu trong C.",
    "5 malloc là hàm cấp phát bộ nhớ của C. Với C++ chúng ta dùng new",
    "6 sizeof là hàm trả về kích thước của kiểu dữ liệu, dùng làm tham số cho hàm malloc"
]

with open('data.txt', 'w') as wf:
    for text in texts:
        wf.write(text + '\n')

with open('data.txt') as wr:
    print("Number of line:", len(wr.readlines()))

# Ghi file vào cuối
with open('data.txt', 'a') as wf:
    wf.write('=> From LTKK with love')

with open('data.txt') as wr:
    texts = wr.readlines()
    print("Number of line:", len(texts))
    print(texts)

Kết quả:

Number of line: 7
Number of line: 8
['0 Kích thước cố định\n', '1 Cần chỉ rõ kích thước trong khi khai báo\n', '2 Kích thước thay đổi trong quá trình thêm/ xóa phần tử\n', '3 Kích thước tối đa phụ thuộc vào bộ nhớ\n', '4 typedef được dùng để định nghĩa một kiểu dữ liệu trong C.\n', '5 malloc là hàm cấp phát bộ nhớ của C. Với C++ chúng ta dùng new\n', '6 sizeof là hàm trả về kích thước của kiểu dữ liệu, dùng làm tham số cho hàm malloc\n', '=> From LTKK with love']

Đọc ghi JSON từ file

Trong phần này, chúng ta sẽ làm việc với tệp tin JSON sử dụng ngôn ngữ Python. Giả sử chúng ta có file JSON như sau:

[
    {
        "id": 1,
        "email": "[email protected]",
        "first": "Torrey",
        "last": "Veum",
        "company": "Hilll, Mayert and Wolf",
        "created_at": "2014-12-25T04:06:27.981Z",
        "country": "Switzerland"
    },
    {
        "id": 2,
        "email": "[email protected]",
        "first": "Micah",
        "last": "Sanford",
        "company": "Stokes-Reichel",
        "created_at": "2014-07-03T16:08:17.044Z",
        "country": "Democratic People's Republic of Korea"
    }
]

Cách đọc file JSON

import json

with open('customer.json') as wr:
    customers = json.load(wr)

for customer in customers:
    print(customer, type(customer))

Kết quả:

{'id': 1, 'email': '[email protected]', 'first': 'Torrey', 'last': 'Veum', 'company': 'Hilll, Mayert and Wolf', 'created_at': '2014-12-25T04:06:27.981Z', 'country': 'Switzerland'} 
{'id': 2, 'email': '[email protected]', 'first': 'Micah', 'last': 'Sanford', 'company': 'Stokes-Reichel', 'created_at': '2014-07-03T16:08:17.044Z', 'country': "Democratic People's Republic of Korea"} 

Ghi dữ liệu từ điển ra file JSON

import json

customers = [
    {
        "id": 1,
        "email": "[email protected]",
        "first": "Torrey",
        "last": "Veum",
        "company": "Hilll, Mayert and Wolf",
        "created_at": "2014-12-25T04:06:27.981Z",
        "country": "Switzerland"
    },
    {
        "id": 2,
        "email": "[email protected]",
        "first": "Micah",
        "last": "Sanford",
        "company": "Stokes-Reichel",
        "created_at": "2014-07-03T16:08:17.044Z",
        "country": "Democratic People's Republic of Korea"
    }
]

with open('customer.json', 'w') as wr:
    json.dump(customers, wr)

# Lưu ý:
# - Với dữ liệu tiếng Việt, hàm `dump()` và `dumps()` đưa toàn bộ về bảng mã ASCII.
#    Do đó, nếu bạn muốn đọc được file JSON khi mở bằng Editor, thêm option `ensure_ascii = False`.
# - Nếu muốn làm đẹp file JSON, hãy thêm option `indent=2` vào hàm `dump()`. Trong đó, 2 số lượng dấu cách (space) dùng để format tệp tin.

customers = [
    {
        "id": 1,
        "email": "[email protected]",
        "first": "Hiếu",
        "last": "Nguyễn Văn",
        "company": "Zalo",
        "created_at": "2014-12-25T04:06:27.981Z",
        "country": "Việt Nam"
    },
    {
        "id": 2,
        "email": "[email protected]",
        "first": "Micah",
        "last": "Sanford",
        "company": "Stokes-Reichel",
        "created_at": "2014-07-03T16:08:17.044Z",
        "country": "Democratic People's Republic of Korea"
    }
]

with open('customer.json', 'w') as wr:
    json.dump(customers, wr, ensure_ascii=False, indent=2)

Kết quả:

[
  {
    "id": 1,
    "email": "[email protected]",
    "first": "Hiếu",
    "last": "Nguyễn Văn",
    "company": "Zalo",
    "created_at": "2014-12-25T04:06:27.981Z",
    "country": "Việt Nam"
  },
  {
    "id": 2,
    "email": "[email protected]",
    "first": "Micah",
    "last": "Sanford",
    "company": "Stokes-Reichel",
    "created_at": "2014-07-03T16:08:17.044Z",
    "country": "Democratic People's Republic of Korea"
  }
]

Như vậy, bài viết đã trình bày các nội dung cần thiết về đọc ghi file trong Python. Với những kiến thức căn bản này, bạn hoàn toàn có thể sử dụng và đáp ứng yêu cầu trong công việc. Chúc bạn học tập tốt!

Tham gia nhóm Lập Trình Không Khó nhé: https://www.facebook.com/groups/1023125804557712/

1