Linux文件描述符(fd)的使用方法与注意事项

一、文件描述符概述

文件描述符是Linux系统中对打开文件的引用,每个进程都有自己的文件描述符表。在进程中打开文件时,会返回一个整型的文件描述符,用来标识该文件。文件描述符的值从0开始,每打开一个文件,描述符的值就会递增。在C语言中,文件描述符用int类型来表示。

在Linux中,文件描述符不仅仅可以表示已经打开的普通文件,还可以用于表示管道操作,套接字、目录和设备等。

二、文件描述符的使用方法

1、打开文件

在Linux中,打开文件的函数为open(),示例代码如下:

#include <fcntl.h>
#include <errno.h>

int fd = open("file.txt", O_RDONLY);
if(fd == -1) {
    perror("open file.txt error:");
    exit(EXIT_FAILURE);
}

上述代码中,指定的文件名为file.txt,文件的打开方式为只读模式,函数返回的是文件描述符,如果返回值等于-1,表示打开文件失败。

2、读写文件

在Linux中,读取和写入文件的函数分别为read()和write(),示例代码如下:

读取文件示例:

#include <unistd.h>
#include <errno.h>

char buffer[1024];
int ret;

ret = read(fd, buffer, sizeof(buffer));
if(ret == -1) {
    perror("read error:");
    exit(EXIT_FAILURE);
}

写入文件示例:

#include <unistd.h>
#include <errno.h>

char buffer[1024] = "Hello World!";
int ret;

ret = write(fd, buffer, sizeof(buffer));
if(ret == -1) {
    perror("write error:");
    exit(EXIT_FAILURE);
}

3、关闭文件

在完成对文件的操作后,需要关闭文件,释放资源。关闭文件的函数为close(),示例代码如下:

#include <unistd.h>

close(fd);

三、文件描述符的注意事项

1、资源限制

系统资源有限,每个进程可以打开的文件数是有限制的。默认情况下,每个进程可以打开的文件数为1024个,可以通过ulimit命令查看。

当进程打开的文件数达到系统限制时,会导致无法打开新的文件,可以通过增加系统限制或者调整进程的逻辑来解决。

2、文件描述符的复制

Linux中的文件描述符是引用文件的方式,可以利用dup() or dup2()函数将一个文件描述符复制到另一个文件描述符,以便将一个已经打开的文件描述符传递给一个函数。

例如:

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int fd1 = open("file1.txt", O_RDONLY);
int fd2 = dup(fd1);

上述代码中,fd2是通过将fd1复制而来的文件描述符,它们引用同一个文件。

3、文件描述符的关闭

在使用文件描述符时,要注意及时关闭文件,否则会浪费系统资源,造成不必要的麻烦。当一个进程以当前用户权限打开一个文件后,该文件的所有权就属于了该进程,而不是当前用户。

如果在打开文件后,删除了该文件,但进程还没关闭该文件,则该文件仍然可以继续访问和修改,因为该文件的所有权已经属于了进程,不受文件删除的影响。

4、文件描述符的作用域

文件描述符的作用域默认情况下只在进程内有效,而无法在进程之间进行传递。如果需要在进程之间传递文件描述符,则可以使用Unix域套接字。

例如:

int socketpair(int domain, int type, int protocol, int sv[2]);

/*创建两个进程之间的管道*/
int fd[2];
socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
pid_t pid;
pid = fork();
if (pid < 0) {
    perror("fork error:");
    return -1;
} else if (pid == 0) {
    /* 子进程向父进程发送信息 */
    char *buffer = "Hello World";
    write(fd[1], buffer, strlen(buffer));
    close(fd[1]);
} else {
    /* 父进程接收子进程发送的信息 */
    char buffer[1024];
    memset(buffer, 0, 1024);
    read(fd[0], buffer, 1024);
    printf("Message from child process: %s\n", buffer);
    close(fd[0]);
}

总结

文件描述符是Linux系统中对打开文件的引用,每个进程都有自己的文件描述符表。在使用文件描述符时,要注意及时关闭文件,否则会浪费系统资源。

文件描述符的作用域默认情况下只在进程内有效,如果需要在进程之间传递文件描述符,则可以使用Unix域套接字。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/230679.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-10 18:18
下一篇 2024-12-10 18:18

相关推荐

  • int类型变量的细节与注意事项

    本文将从 int 类型变量的定义、声明、初始化、范围、运算和类型转换等方面,对 int 类型变量进行详细阐述和讲解,帮助读者更好地掌握和应用 int 变量。 一、定义与声明 int…

    编程 2025-04-29
  • vue下载无后缀名的文件被加上后缀.txt,有后缀名的文件下载正常问题的解决

    本文旨在解决vue下载无后缀名的文件被加上后缀.txt,有后缀名的文件下载正常的问题,提供完整的代码示例供参考。 一、分析问题 首先,需了解vue中下载文件的情况。一般情况下,我们…

    编程 2025-04-29
  • Python中init方法的作用及使用方法

    Python中的init方法是一个类的构造函数,在创建对象时被调用。在本篇文章中,我们将从多个方面详细讨论init方法的作用,使用方法以及注意点。 一、定义init方法 在Pyth…

    编程 2025-04-29
  • 如何在Java中拼接OBJ格式的文件并生成完整的图像

    OBJ格式是一种用于表示3D对象的标准格式,通常由一组顶点、面和纹理映射坐标组成。在本文中,我们将讨论如何将多个OBJ文件拼接在一起,生成一个完整的3D模型。 一、读取OBJ文件 …

    编程 2025-04-29
  • 为什么用cmd运行Java时需要在文件内打开cmd为中心

    在Java开发中,我们经常会使用cmd在命令行窗口运行程序。然而,有时候我们会发现,在运行Java程序时,需要在文件内打开cmd为中心,这让很多开发者感到疑惑,那么,为什么会出现这…

    编程 2025-04-29
  • Python程序文件的拓展

    Python是一门功能丰富、易于学习、可读性高的编程语言。Python程序文件通常以.py为文件拓展名,被广泛应用于各种领域,包括Web开发、机器学习、科学计算等。为了更好地发挥P…

    编程 2025-04-29
  • Python中读入csv文件数据的方法用法介绍

    csv是一种常见的数据格式,通常用于存储小型数据集。Python作为一种广泛流行的编程语言,内置了许多操作csv文件的库。本文将从多个方面详细介绍Python读入csv文件的方法。…

    编程 2025-04-29
  • Python将矩阵存为CSV文件

    CSV文件是一种通用的文件格式,在统计学和计算机科学中非常常见,一些数据分析工具如Microsoft Excel,Google Sheets等都支持读取CSV文件。Python内置…

    编程 2025-04-29
  • Python zipfile解压文件乱码处理

    本文主要介绍如何在Python中使用zipfile进行文件解压的处理,同时详细讨论在解压文件时可能出现的乱码问题的各种解决办法。 一、zipfile解压文件乱码问题的根本原因 在P…

    编程 2025-04-29
  • Python如何导入py文件

    Python是一种开源的高级编程语言,因其易学易用和强大的生态系统而备受青睐。Python的import语句可以帮助用户将一个模块中的代码导入到另一个模块中,从而实现代码的重用。本…

    编程 2025-04-29

发表回复

登录后才能评论