什么是文件描述符?可实践性教程

127 阅读2分钟

文件描述符(File Descriptor)是一个非负整数,它代表操作系统内核为程序打开的一个文件、套接字或其他数据流的引用。当程序打开一个文件或创建一个套接字时,操作系统通常会返回一个文件描述符,之后该程序就可以使用这个描述符来读取、写入或进行其他操作。

文件描述符的一些基础概念:

  1. 标准文件描述符:当你启动一个程序时,它通常会自动拥有三个文件描述符:

    • 0 - 标准输入(stdin)
    • 1 - 标准输出(stdout)
    • 2 - 标准错误(stderr)
  2. 范围:在大多数系统中,文件描述符的值开始于3(因为0、1和2已经被预留)。

  3. 生命周期:当一个程序结束运行时,它的所有文件描述符通常都会被操作系统关闭。

  4. 操作:使用系统调用如open(), socket(), pipe()等,可以获取新的文件描述符;使用close()可以关闭一个文件描述符。

实践:使用文件描述符在C语言中操作文件

创建c文件:testfd.c

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

#define NUM_OPEN_TIMES 20  // 定义打开文件的次数

int main() {
    int fds[NUM_OPEN_TIMES];
    char buffer[NUM_OPEN_TIMES][100];  // 为每个文件描述符都分配一个缓冲区

    // 1. 打开文件并获取文件描述符
    for (int i = 0; i < NUM_OPEN_TIMES; i++) {
        fds[i] = open("test.txt", O_RDONLY);
        if(fds[i] == -1) {
            perror("Error opening file");
            printf("fd on iteration %d: %d\n", i, fds[i]);
            return 1;
        }
        printf("Opened fd on iteration %d: %d\n", i, fds[i]);
    }

    // 2. 使用文件描述符读取文件内容
    for (int i = 0; i < NUM_OPEN_TIMES; i++) {
        ssize_t bytes_read = read(fds[i], buffer[i], sizeof(buffer[i])-1);
        if (bytes_read < 0) {
            perror("Error reading file");
            return 1;
        }
        buffer[i][bytes_read] = '\0';  // 确保buffer以null结尾

        // 3. 打印读取的内容到标准输出
        printf("Read from file (iteration %d): %s\n", i, buffer[i]);
    }

    // 4. 关闭文件描述符
    for (int i = 0; i < NUM_OPEN_TIMES; i++) {
        close(fds[i]);
    }

    return 0;
}

上述代码完成了以下操作:

  1. 使用open()系统调用打开文件并返回一个文件描述符。
  2. 使用read()系统调用通过文件描述符读取文件内容。
  3. 使用printf()打印读取的内容。
  4. 使用close()系统调用关闭文件描述符。

要运行这个例子:

  1. 创建一个名为test.txt的文件,并写入一些文本。
  2. 编译上述C程序。gcc -C testfd.c
  3. 运行程序。./a.out
  4. 如果一切正常,你应该会在终端看到test.txt的内容。

image.png

注意:这只是一个简单的示例,实际应用中可能需要更复杂的错误处理和更高级的文件操作。