Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Lập Trình C

Làm chủ system call read() trong C: Hướng dẫn toàn diện

Ngôn ngữ C cung cấp nhiều hàm đọc tệp, phổ biến nhất là read() và fread(). Ngoài ra còn có getchar() để đọc từng ký tự. Việc nắm vững các hàm xử lý tệp, cách gọi, tham số đầu vào/ra là cần thiết để lưu trữ và xử lý thông tin trên hệ thống.

Bài viết này trên Linuxhint sẽ hướng dẫn bạn sử dụng hàm read() để đọc tệp, bao gồm cú pháp, mô tả hoạt động, các tham số, kiểu dữ liệu và cách khai báo đúng đắn. Sau đó áp dụng vào ví dụ thực tế. Cuối cùng có phần chuyên biệt về phát hiện và xác định lỗi khi dùng read().

Cú pháp hàm read()

size_t read(int fd, void *buf, size_t count);

Mô tả hàm read()

Hàm read() đọc nội dung của tệp đã mở được chỉ định bởi bộ mô tả tệp (file descriptor) trong tham số fd. Nó sao chép dữ liệu vào bộ đệm trỏ bởi buf với số byte là count. fd là số nguyên trả về bởi open() khi mở tệp.

Nếu thành công, read() trả về số byte đã đọc. Trả về 0 nghĩa là đã đọc hết tệp (EOF), -1 nghĩa là xảy ra lỗi. Mã lỗi cụ thể được lưu trong biến toàn cục errno (khai báo trong errno.h). Phần sau sẽ mô tả các lỗi thường gặp và cách xử lý.

Hàm read() được khai báo trong unistd.h. Để sử dụng, cần include:

#include <unistd.h>

Ví dụ: Đọc tệp với read()

Chúng ta tạo tệp example.txt trong thư mục Documents chứa đoạn văn đầu tiên của bài viết. Các bước:

  1. Include các header cần thiết: stdio.h, stdlib.h, unistd.h, fcntl.h.
  2. Khai báo fd (file descriptor), bộ đệm buff[1024], mảng path lưu đường dẫn tệp.
  3. Gọi open(path, O_RDONLY) để mở tệp chỉ đọc, lưu descriptor vào fd.
  4. Gọi read(fd, buff, 1024) đọc nội dung vào buff.
  5. In ra màn hình bằng printf.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int main() {
    int fd;
    char buff[1024];
    char path[] = "Documents/example.txt";
    fd = open(path, O_RDONLY);
    read(fd, buff, 1024);
    printf("\n\n%s\n\n", buff);
    return 0;
}

Làm chủ system call read() trong C: Hướng dẫn toàn diện

Phát hiện và xác định lỗi

Khi read() trả về -1, có lỗi. Cách đơn giản nhất là kiểm tra bằng if:

int n = read(fd, buff, 1024);
if (n == -1) {
    printf("Lỗi khi đọc tệp.\n");
}

Mã lỗi lưu trong errno (include errno.h). Dùng switch trên errno để xác định lỗi. Bảng dưới liệt kê một số lỗi phổ biến:

Định nghĩaGiá trị errnoMô tả
EAGAIN11Thử lại
EBADF9Số tệp không hợp lệ
EDESTADDRREQ89Yêu cầu địa chỉ đích
EFAULT14Địa chỉ không đúng
EFBIG27Tệp quá lớn
EINTR4Lời gọi hệ thống bị ngắt
EINVAL22Tham số không hợp lệ
EIO5Lỗi I/O
EPERM1Thao tác không được phép

Ví dụ: truyền descriptor âm (99999999) để gây lỗi, dùng switch xác định:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

int main() {
    int fd, n;
    char buff[1024];
    char path[] = "Documents/example.txt";
    fd = open(path, O_RDONLY);

    n = read(99999999, buff, 1024);
    if (n == -1) {
        switch(errno) {
            case EBADF:
                printf("Số tệp không hợp lệ. Lỗi: %i\n", errno);
                break;
            case EINVAL:
                printf("Tham số không hợp lệ. Lỗi: %i\n", errno);
                break;
            case EIO:
                printf("Lỗi I/O. Lỗi: %i\n", errno);
                break;
        }
    }
    return 0;
}

Làm chủ system call read() trong C: Hướng dẫn toàn diện

Kết quả cho thấy lỗi EBADF khi descriptor không hợp lệ.

Kết luận

Bài viết đã trình bày cách dùng read(), cú pháp, lý thuyết, ví dụ thực tế mở/đọc tệp, và phương pháp phát hiện/xác định lỗi qua errno.