open返回得到的文件描述符fd可以进行复制,复制成功之后可以得到一个新的文件 描述符,使用新的文件描述符和旧的文件描述符都可以对文件进行IO操作,复制得到的文件描述符和旧的文件描述符拥有相同的权限。
在Linux系统下,可以使用dupdup2这两个系统调用对文件描述符进行复制
1.dup
用于并可以多次复制文件描述符,复制得到的文件描述符与原文件描述符都指向同一个文件表,它们的文件偏移量是一样的,所以写入的内容不会被覆盖
1)头文件
#include <unistd.h>
2)函数原型
int dup(int oldfd);
3)参数
oldfd:表示需要被复制的文件描述符。
4)返回值
成功时将返回一个新的文件描述符,由操作系统分配,分配置原则遵循文件描述符分配原则;如果复制失败将返回-1,并且会设置errno值。
5)示例:(复制一个文件描述符,并循环写入特定内容)
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main()
{
char buf[20] = "duptest";
int fd1, fd2, i;
fd1 = open("test", O_RDWR | O_CREAT | O_TRUNC, 0666);     //打开文件ftest
if (fd1 < 0) {
printf("error: ftest open\n");
return -1;
}
fd2 = dup(fd1);                    //复制fd1
if (fd2 < 0) {
printf("error: dup\n");
close(fd1);
return -1;
}
for (i = 0; i < 7; i++) {               //循环7次,写入duptest
if ( write(fd1, &buf, 1) < 0 ) {       //先向fd1写入
printf("error: fd1 write, i=%d\n", i);
close(fd1);
close(fd2);
return -1;
}
if ( write(fd2, &buf, 1) < 0 ) {       //再向fd2写入
printf("error: fd2 write, i=%d\n", i);
close(fd1);
close(fd2);
return -1;
}
}
if (lseek(fd1, 0, SEEK_SET) < 0) {          //将位置指针设置到文件开头
printf("error: fd1 lseek\n");
close(fd1);
close(fd2);
return -1;
}
if (read(fd1, buf, 14) < 0) {             //读取文件内容
printf("error: fd1 read\n");
close(fd1);
close(fd2);
return -1;
}
printf("fd1=%d,fd2=%d,dup test:%s\n", fd1, fd2, buf);
close(fd1);
close(fd2);
return 0;
}
6)编译运行并查看测试结果
fd1=3,fd2=4,dup test:dduupptteessttst   //打印内容是连续写的,说明复制的文件描述符共用文件偏移量
2.dup2
相比于dupdup2可以手动指定复制得到的文件描述符,而不需要遵循文件描述符分配原则
1)头文件
#include <unistd.h>
2)函数原型
int dup2(int oldfd, int newfd);
3)参数
oldfd:需要被复制的文件描述符。
newfd:指定一个新的文件描述符(当前进程没有使用到的文件描述符)。
4返回值
成功时将返回一个手动指定的文件描述符newfd;如果复制失败将返回-1,并且会设置errno
5)示例:(复制一个文件描述符,指定新的文件描述符为10)
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main()
{
int fd1, fd2;
fd1 = open("test", O_RDWR | O_CREAT | O_TRUNC, 0666);
if (fd1 < 0) {
printf("error: test open\n");
return -1;
}
fd2 = dup2(fd1, 10);
if (fd2 < 0) {
printf("error: dup2\n");
close(fd1);
return -1;
}
printf("fd1=%d,fd2=%d\n", fd1, fd2);
close(fd1);
close(fd2);
return 0;
}
6)编译运行并查看测试结果
fd1=3,fd2=10

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    Powered by Discuz! X3.5  © 2001-2013 Comsenz Inc.