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