基于文件描述符的文件操作(五):文件描述符的复制

By AverageJoeWang
 标签:

一.概述

文件描述符是Linux系统对于打开的文件所维护的一个计数值,有时候在操作的过程中需要对文件描述符进行复制,Linux/Unix系统提供了dup与dup2两个函数接口进行调用,本篇笔记主要记录他们之间的异同点与使用方法

二.文件描述符的复制

2.1.dup与dup2原型

#include <unistd.h>   //头文件包含
int dup(int oldfd);
int dup2(int oldfd, int newfd);
  • dup函数说明
  • 函数说明:dup()用来复制参数oldfd 所指的文件描述词, 并将它返回.
  • 此新的文件描述词和参数oldfd 指的是同一个文件, 共享所有的锁定、读写位置和各项权限或旗标.
  • 例如, 当利用lseek()对某个文件描述词作用时, 另一个文件描述词的读写位置也会随着改变.
  • 不过, 文件描述词之间并不共享close-on-exec 旗标.
  • 返回值:当复制成功时, 则返回最小及尚未使用的文件描述词. 若有错误则返回-1, errno 会存放错误代码.
  • dup2函数说明
  • dup2()用来复制参数oldfd 所指的文件描述词, 并将它拷贝至参数newfd 后一块返回.
  • 若参数newfd为一已打开的文件描述词, 则newfd 所指的文件会先被关闭.
  • dup2()所复制的文件描述词, 与原来的文件描述词共享各种文件状态
  • 返回值:当复制成功时, 则返回最小及尚未使用的文件描述词. 若有错误则返回-1, errno 会存放错误代码.
  • 附加说明:
  • dup2()相当于调用fcntl(oldfd, F_DUPFD, newfd);函数

2.2.dup例子

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <strings.h>
#include <stdlib.h>
#include <stdio.h>
using std::cout;
using std::endl;

int main(int argc, char* argv[])
{
    int fd = open(argv[1], O_RDONLY|O_CREAT);
    if(-1 == fd)
    {
        perror("open error");
        return -1;
    }
    char buf[128];
    bzero(buf, sizeof(buf));
    int fd2 = fd;//类似于C语言的指针,当释放close掉一个的时候,另一个已经不能操作
    int fd3 = dup(fd);//内核的文件打开引用计算+1,变成2,当一个释放的时候,另一个还是可以继续访问文件
    close(fd);
    printf("read : %d\n", read(fd3, buf, sizeof(buf)-1));
    close(fd3);
    return 0;
}

2.3.dup2例子

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
    int fd, copyfd;
    fd = open("./log.txt", O_RDWR);
    //指定文件描述符号为1000
    copyfd = dup2(fd, 1000);
    //打印fd和copyfd,应当输出3 1000
    printf("%d %d\n", fd, copyfd);
    return 0;
}