六、Linux系统编程-文件和IO(四)文件共享、复制文件描述符

本文详细介绍了文件描述符的使用,包括如何在不同进程间打开和共享文件,通过实例展示了文件描述符如何实现文件的多次打开及共享,以及复制文件描述符的功能及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、文件共享

每个进程都有一个自己的文件描述符表。在一个进程中,一个文件被打开之后,会分配一个文件描述符,一个文件表表项,一个v节点表。其中文件表保存文件状态,包括:读、写、追加、同步、非阻塞等。其中文件表项是不能共享的,文件被打开一次,就会分配一个文件表项;v节点表示可以共享的,两个不同的文件表项可以指向同一个v节点表。

(1)、一个进程打开两个文件模型



(2)、一个进程两次打开同一个文件



我们可以通过例子证明上面的模型,示例:

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

#define ERR_EXIT(m) \
        do \
        { \
                perror(m); \
                exit(EXIT_FAILURE); \
        }while(0)

int main()
{
        int fd1,fd2;
        char buf[1024];
        fd1 = open("aa.txt",O_RDWR);
        if (fd1 == -1)
                ERR_EXIT("open error");
        read(fd1,buf,5);
        printf("read1:%s\n",buf);
        fd2 = open("aa.txt",O_RDWR);
        if(fd2 == -1)
                ERR_EXIT("open error");
        read(fd2,buf,5);
        printf("read2:%s\n",buf);

        write(fd1,"AAAaa",5);
        read(fd2,buf,5);
        printf("read fd2:%s\n",buf)
        close(fd1);
        close(fd2);
        return 0;
}
执行结果:

s@ubuntu:~/sys$ cat aa.txt 
abcdeAAAaa
s@ubuntu:~/sys$ gcc open2.c 
s@ubuntu:~/sys$ ./a.out 
read1:abcde
read2:abcde
read fd2:AAAaa
s@ubuntu:~/sys$ 
说明一个进程打开两次的相同文件会有两个文件表项,但是共享v节点。

(3)、两个进程打开同一个文件


两个进程打开一个文件描述符可以相同,因为每个进程都有自己的文件描述符表。示例:

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

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

#define ERR_EXIT(m) \
        do \
        { \
                perror(m); \
                exit(EXIT_FAILURE); \
        }while(0)
#define MAJOR(a) (int)((unsigned short)a>>8)
#define MINOR(a) (int)((unsigned short)a & 0xFF)
int filetype(struct stat *buf);
int main(int argc,char* argv[])
{
        int infd;
        int outfd;
        int ret;
        if ((ret = fork()) > 0)
        {
                infd = open("aa.txt",O_RDONLY);
                printf("in:%d\n",infd);
        }
        else
        {
                outfd = open("aa.txt",O_WRONLY);
                printf("out:%d\n",outfd);
        }
        wait(&ret);
        return 0;
}
结果:

in:3
out:3
文件描述符相同,说明每个进程都有自己的文件描述符表。

(4)、复制文件描述符

复制之前:


复制之后:



可以通过复制文件描述符实现输出重定向到文件,示例:

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

#define ERR_EXIT(m) \
        do \
        { \
                perror(m); \
                exit(EXIT_FAILURE); \
        }while(0)

int main()
{
        int fd;
        fd = open("aa.txt",O_WRONLY);
        if (fd == -1)
                ERR_EXIT("open error");
        close(1);
        dup(fd);//等价于dup2(fd,0);
        printf("Hello\n");
        return 0;
}
结果"Hello"没有输出到屏幕,而是输出到文件,因为此时标准输出文件描述符1已经指向打开文件aa.txt。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值