linux 文件描述符


一、文件描述符介绍

每个进程都有一张文件描述符的表,程序运行起来后标准输入、标准输出、标准错误输出设备是默认打开的,对应的文件描述符 0、1、2 记录在表中
在打开其他文件时,系统会返回该进程文件描述符表中最小可用的文件描述符,并将此文件描述符记录在表中
Linux 中一个进程最多只能打开 NR_OPEN_DEFAULT(1024)个文件,故当文件不再使用时应及时调用 close() 函数关闭文件,释放文件描述符资源

二、int dup(int oldfd);

1. 复制文件描述符

新的文件描述符是调用进程文件描述符表中最小可用的文件描述符,最终 oldfd 和新的文件描述符指向同一个文件,分派最小文件描述符:

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

int main()
{
    int fd1, fd2;
    fd1 = open("1.txt", O_CREAT|O_WRONLY, 0666);
    fd2 = dup(fd1); // 通过 fd1 复制 fd2, 最终 fd1 和 fd2 都指向 1.txt
    printf("fd1 ============== %d\n", fd1);
    printf("fd2 ============== %d\n", fd2);
    char *buf1 = "this is a test for fd1\n";
    char *buf2 = "this is a test for fd2\n";
    write(fd1, buf1, strlen(buf1));
    write(fd2, buf2, strlen(buf2));
    close(fd1); // 关闭文件描述符,两个都需要关闭
    close(fd2);
    
    return 0;
}

2. 文件描述符重定向

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

int main()
{
    int fd1, fd2;
    fd1 = open("1.txt", O_CREAT|O_WRONLY, 0666);
    printf("fd1 ============== %d\n", fd1);

    // 描述符 1 默认指向标准输出(显示屏),关闭该描述符就空闲了,就不再指向标准输出,成为最小可用文件描述符
    close(1);

    // fd1, fd2 都指向 1.txt,系统会给 fd2 分配最小可用的文件描述符,即 fd2 = 1
    fd2 = dup(fd1);

    // printf() 最终调用 write(1,xxx),默认文件描述符 1 指向标准输出,所以 printf() 内容默认显示到屏幕
    // 现在文件描述符 1 指向 1.txt,所以此时 printf() 的内容不会打印到屏幕上,而是写入文件 1.txt
    printf("fd2 ============== %d\n", fd2);

    close(fd1);
    close(fd2);
    
    return 0;
}

三、int dup2(int oldfd, int newfd);

功能和 dup() 完全一样,但是 dup2() 复制出来的新文件描述符可以指定任意一个合法的数字
如果指定的数字已经被占用(和某个文件有关联),此函数会自动 close() 断开这个数字和那个文件的关联,再来使用这个合法数字
这两个系统调用都是用来复制一个文件描述符,使新文件描述符和旧文件描述符标识同一个文件。操作这两个文件描述符的任何一个,都能操作所对应的文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值