Quản lý Tệp và Thư mục với Module os trong Python

Module os trong Python là một phần thiết yếu của thư viện chuẩn, cung cấp các hàm mạnh mẽ để tương tác với hệ điều hành. Nó cho phép các lập trình viên thực hiện các tác vụ quản lý tệp và thư mục một cách dễ dàng và nhất quán trên các nền tảng khác nhau như Windows, Linux hay macOS mà không cần phải điều chỉnh mã nguồn.

Các Thao tác Cơ bản với Tệp và Thư mục

Dưới đây là một số chức năng cơ bản thường được sử dụng từ module os:

1. Lấy và Thay đổi Thư mục Làm việc Hiện tại

  • os.getcwd(): Trả về một chuỗi đại diện cho đường dẫn tuyệt đối của thư mục mà chương trình Python đang chạy.
  • os.chdir(path): Thay đổi thư mục làm việc hiện tại của chương trình sang đường dẫn được chỉ định.
import os

# Lấy thư mục làm việc hiện tại
current_dir = os.getcwd()
print(f"Thư mục làm việc hiện hành: {current_dir}")

# Thay đổi thư mục (ví dụ: chuyển lên một cấp)
# os.chdir("..") 
# print(f"Thư mục làm việc sau khi thay đổi: {os.getcwd()}")

2. Liệt kê và Xóa Tệp/Thư mục

  • os.listdir(path='.'): Trả về một danh sách chứa tên của tất cả các tệp và thư mục con trong đường dẫn được cung cấp. Nếu không có đối số, nó sẽ liệt kê nội dung của thư mục hiện hành.
  • os.remove(path): Dùng để xóa một tệp cụ thể. Hãy cẩn thận khi sử dụng hàm này vì nó sẽ xóa vĩnh viễn tệp.
  • os.rmdir(path): Xóa một thư mục rỗng.
# Liệt kê nội dung thư mục hiện tại
print("\nNội dung thư mục hiện tại:")
for item in os.listdir():
    print(f"- {item}")

# Ví dụ về xóa tệp (đã được comment để tránh xóa nhầm)
# try:
#     with open("file_to_delete.txt", "w") as f:
#         f.write("Đây là tệp sẽ bị xóa.")
#     print("\n'file_to_delete.txt' đã được tạo.")
#     os.remove("file_to_delete.txt")
#     print("'file_to_delete.txt' đã bị xóa.")
# except OSError as e:
#     print(f"Lỗi khi xóa tệp: {e}")

3. Thực thi Lệnh Hệ thống

  • os.system(command): Chạy một lệnh shell (terminal) và trả về mã thoát của lệnh.
# Thực thi lệnh 'ls -l' trên Linux/macOS hoặc 'dir' trên Windows
# exit_code = os.system("ls -l") # Thay bằng "dir" nếu dùng Windows
# print(f"\nMã thoát của lệnh: {exit_code}")

Thao tác với Đường dẫn (Module os.path)

Module os.path cung cấp các hàm chuyên biệt để xử lý đường dẫn tệp và thư mục, giúp tách, ghép hoặc kiểm tra các thành phần của đường dẫn một cách hiệu quả.

1. Lấy Đường dẫn Tuyệt đối

  • os.path.abspath(path): Trả về phiên bản đường dẫn tuyệt đối của path.
relative_path = "my_python_script.py"
absolute_path = os.path.abspath(relative_path)
print(f"Đường dẫn tương đối: {relative_path}")
print(f"Đường dẫn tuyệt đối: {absolute_path}")

2. Tách và Ghép Đường dẫn

  • os.path.split(path): Tách đường dẫn thành một cặp (đầu, đuôi), trong đó 'đuôi' là thành phần cuối cùng của đường dẫn (tên tệp hoặc thư mục cuối cùng) và 'đầu' là phần còn lại.
  • os.path.join(path1, path2, ...): Kết hợp một hoặc nhiều thành phần đường dẫn một cách thông minh, xử lý các dấu phân cách hệ thống một cách chính xác.
full_path_example = "/home/user/documents/monthly_report.pdf"
head, tail = os.path.split(full_path_example)
print(f"\nĐường dẫn gốc: {full_path_example}")
print(f"Phần đầu (directory): {head}")
print(f"Phần đuôi (file/last folder): {tail}")

# Ghép đường dẫn
dir_part = "/usr/local"
sub_dir_part = "bin"
exec_file = "app_runner"
combined_path = os.path.join(dir_part, sub_dir_part, exec_file)
print(f"Đường dẫn đã ghép: {combined_path}")

3. Lấy Tên Thư mục và Tên Tệp

  • os.path.dirname(path): Trả về tên thư mục của đường dẫn đã cho. Tương đương với phần 'đầu' từ os.path.split().
  • os.path.basename(path): Trả về tên tệp hoặc thư mục cuối cùng trong đường dẫn. Tương đương với phần 'đuôi' từ os.path.split().
path_to_analyze = "/data/logs/application.log"
print(f"Đường dẫn: {path_to_analyze}")
print(f"Tên thư mục: {os.path.dirname(path_to_analyze)}")
print(f"Tên tệp: {os.path.basename(path_to_analyze)}")

Thông tin về Tệp và Trạng thái

Module os.path cũng cho phép truy xuất thông tin chi tiết về tệp và thư mục.

1. Lấy Kích thước Tệp

  • os.path.getsize(path): Trả về kích thước của tệp tính bằng byte. Đối với thư mục, nó thường trả về 0 trên nhiều hệ thống.
# Tạo một tệp nhỏ để kiểm tra
temp_file_name = "test_file_size.txt"
with open(temp_file_name, "w") as f:
    f.write("Đây là nội dung của tệp kiểm tra kích thước.")
file_size = os.path.getsize(temp_file_name)
print(f"\nKích thước của '{temp_file_name}': {file_size} bytes")
os.remove(temp_file_name) # Xóa tệp tạm thời

2. Thời gian Truy cập/Sửa đổi/Tạo

  • os.path.getmtime(path): Thời gian sửa đổi tệp gần nhất.
  • os.path.getatime(path): Thời gian truy cập tệp gần nhất.
  • os.path.getctime(path): Thời gian tạo (trên Windows) hoặc thời gian thay đổi metadata (trên Unix).

Tất cả các hàm này đều trả về số giây kể từ kỷ nguyên (epoch - thường là 01/01/1970 UTC).

import datetime

# Sử dụng một tệp hiện có để minh họa
file_for_time = __file__ # Lấy đường dẫn của chính script này
if os.path.exists(file_for_time):
    modified_ts = os.path.getmtime(file_for_time)
    accessed_ts = os.path.getatime(file_for_time)
    created_ts = os.path.getctime(file_for_time)

    print(f"\nThông tin thời gian cho '{os.path.basename(file_for_time)}':")
    print(f"  Thời gian sửa đổi: {datetime.datetime.fromtimestamp(modified_ts)}")
    print(f"  Thời gian truy cập: {datetime.datetime.fromtimestamp(accessed_ts)}")
    print(f"  Thời gian tạo/meta change: {datetime.datetime.fromtimestamp(created_ts)}")

3. Kiểm tra Sự tồn tại của Đường dẫn

  • os.path.exists(path): Trả về True nếu đường dẫn (tệp hoặc thư mục) tồn tại, False nếu không.
print(f"\nTệp '{os.path.basename(__file__)}' có tồn tại không? {os.path.exists(__file__)}")
print(f"Thư mục 'non_existent_folder' có tồn tại không? {os.path.exists('non_existent_folder')}")

Các Hằng số Hệ thống Cụ thể

Module os cũng định nghĩa một số hằng số hữu ích để làm việc với các quy ước tên tệp và đường dẫn khác nhau của hệ điều hành.

  • os.sep: Ký tự phân cách đường dẫn (ví dụ: \ trên Windows, / trên Linux/macOS).
  • os.extsep: Ký tự phân cách phần mở rộng tệp (thường là .).
  • os.pathsep: Ký tự phân cách các đường dẫn trong biến môi trường (ví dụ: ; trên Windows, : trên Linux/macOS).
  • os.linesep: Ký tự phân cách dòng (ví dụ: \r\n trên Windows, \n trên Linux/macOS).
print(f"\nKý tự phân cách đường dẫn: '{os.sep}'")
print(f"Ký tự phân cách phần mở rộng: '{os.extsep}'")
print(f"Ký tự phân cách biến môi trường PATH: '{os.pathsep}'")
print(f"Ký tự phân cách dòng: '{repr(os.linesep)}'") # repr() để hiển thị ký tự đặc biệt

Ví dụ Thực tế: Tìm Tệp được Sửa đổi Gần đây nhất

Trong các kịch bản thực tế, đặc biệt là trong tự động hóa kiểm thử hoặc xử lý dữ liệu, việc tìm tệp được tạo hoặc sửa đổi gần đây nhất trong một thư mục là rất phổ biến. Dưới đây là một ví dụ về cách thực hiện điều này:

import os
import time
import shutil # Để dọn dẹp thư mục tạm thời

def find_latest_file_by_modification_time(target_directory):
    """
    Tìm và trả về đường dẫn tuyệt đối của tệp được sửa đổi gần đây nhất
    trong thư mục được chỉ định.
    Trả về None nếu thư mục không tồn tại hoặc không có tệp nào.
    """
    if not os.path.isdir(target_directory):
        print(f"Lỗi: '{target_directory}' không phải là một thư mục hợp lệ hoặc không tồn tại.")
        return None

    all_files_in_dir = []
    for entry_name in os.listdir(target_directory):
        full_entry_path = os.path.join(target_directory, entry_name)
        if os.path.isfile(full_entry_path): # Chỉ xem xét các tệp, bỏ qua thư mục con
            all_files_in_dir.append(full_entry_path)

    if not all_files_in_dir:
        print(f"Không có tệp nào trong thư mục '{target_directory}'.")
        return None

    # Sắp xếp danh sách các tệp theo thời gian sửa đổi (tăng dần)
    # Tệp cuối cùng trong danh sách sẽ là tệp mới nhất
    all_files_in_dir.sort(key=lambda file_path: os.path.getmtime(file_path))

    return all_files_in_dir[-1]

# --- Ví dụ sử dụng ---
# Tạo một thư mục tạm thời và một vài tệp giả để minh họa
temp_report_folder = "temp_generated_reports"
if os.path.exists(temp_report_folder):
    shutil.rmtree(temp_report_folder) # Xóa thư mục nếu đã tồn tại để đảm bảo sạch sẽ
os.makedirs(temp_report_folder)

# Tạo các tệp với thời gian sửa đổi khác nhau
with open(os.path.join(temp_report_folder, "report_old.txt"), "w") as f:
    f.write("Báo cáo cũ.")
time.sleep(0.1) # Dừng một chút để đảm bảo thời gian sửa đổi khác nhau
with open(os.path.join(temp_report_folder, "report_medium.txt"), "w") as f:
    f.write("Báo cáo trung bình.")
time.sleep(0.1)
with open(os.path.join(temp_report_folder, "report_latest.txt"), "w") as f:
    f.write("Báo cáo mới nhất.")

print(f"\nKiểm tra thư mục: '{temp_report_folder}'")
latest_document_path = find_latest_file_by_modification_time(temp_report_folder)

if latest_document_path:
    print(f"Tệp được sửa đổi gần đây nhất là: {latest_document_path}")

# Dọn dẹp thư mục tạm thời sau khi hoàn thành
# shutil.rmtree(temp_report_folder)
# print(f"Thư mục '{temp_report_folder}' đã được xóa.")

Thẻ: python os module file management directory operations path manipulation

Đăng vào ngày 6 tháng 7 lúc 11:22