3.12 dup2函数-文件描述符复制

来源:互联网 发布:郑州seo薪资 编辑:程序博客网 时间:2024/05/23 02:06

dup2函数用于复制一个现存的文件描述符,函数原型如下:

#include <unistd.h>int dup2(int filedes, int filedes2);

返回值:若复制成功则返回新文件描述符,若出错则返回-1。

参数:

1、filedes现存的文件描述符。

2、filedes2指定的要生成的新文件描述符。

说明:

1、若filedes2是一个已存在的文件描述符,filedes2会先被关闭再根据filedes复制一个新文件描述符;

2、若filedesfiledes2相等,filedes不会被关闭,而是直接返回。

3、与dup函数一样,dup2函数复制出来的新文件描述符filedes2与原文件描述符filedes共享一个文件表项。

4、dup2函数与dup函数的不同是:dup根据当前可用文件描述符中的最小值复制新文件描述符,dup2则可以任意指定一个文件描述符。


实例 x.3.12.2.c

#include <fcntl.h>#include <unistd.h>#include <stdio.h>#define BUFFSIZE 256int main(void){    char         filepath[] = "/tmp/myfile"; /*待操作文件路径*/    int          f_id1, f_id2;               /*文件描述符*/        ssize_t      nwrite;                     /*实际写入字节书*/    size_t       nbytes;                     /*要写入的字节书*/    off_t        offset;                     /*文件指针偏移量*/    char         buf[BUFFSIZE] = "0123456789"; /*待写入数据*//*打开文件,获取文件描述符*/    f_id1 = open(filepath, O_RDWR | O_CREAT);    if (f_id1 == -1) {        printf("open error for %s\n", filepath);        return 1;    }    f_id2 = dup2(f_id1, 8); /*复制文件描述符,指定的文件描述符为8*/    if (f_id2 == -1) {        printf("dup error for f_id2\n");        return 2;    }    printf("f_id1:%d\n", f_id1);    printf("f_id2:%d\n", f_id2);/*把文件指针移动到文件开始处*/    offset = lseek(f_id1, 0, SEEK_SET);    if (offset == -1) {        printf("lseek error for %s\n", filepath);        return 3;    }/*通过文件描述符f_id1写入3字节数据[0-2]*/    nbytes = 3;    nwrite = write(f_id1, buf, nbytes);    if (nwrite == -1) {        printf("write error for f_id1(%d)\n", f_id1);        return 4;    }/*通过文件描述符f_id2写入7字节数据[3-9]*/    nbytes = 7;    nwrite = write(f_id2, (buf + 3), nbytes);    if (nwrite == -1) {        printf("write error for f_id2(%d)\n", f_id2);        return 5;    }    close(f_id1);    close(f_id2);}

编译与执行:
[root@localhost unixc]# rm -f /tmp/myfile
[root@localhost unixc]# cc x.3.12.2.c
[root@localhost unixc]# ./a.out
f_id1:3
f_id2:8
[root@localhost unixc]# cat /tmp/myfile
0123456789[root@localhost unixc]#

分析:

1、复制出来的新文件描述符f_id2为指定值8;

2、新复制出来的文件描述符f_id2与被复制的文件描述符f_id1共享一个文件表项:代码中第二次写操作是通过文件描述符f_id2来执行,并且没有调用lseek重新定位,但第二次写入并不覆盖第一次写入。