dup 与dup2函数
Linux c 函数
#include<unistd.h>
int dup(int fd);
int dup2(int fd1,int fd2);
两个均为复制一个现存的文件的描述
两个函数的返回:若成功为新的文件描述,若出错为-1;
由dup返回的新文件描述符一定是当前可用文件描述中的最小数值。用dup2则可以用fd2参数指定新的描述符数值。如果fd2已经打开,则先关闭。若fd1=fd2,则dup2返回fd2,而不关闭它。通常使用这两个系统调用来重定向一个打开的文件描述符。
重定向
一般在程序实现重定向都会用到dup2函数。
文件描述符0 --> 标准输出
文件描述符1 -->标准输入
文件描述符2–>标准错误
例子1:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/types.h>
int main(void)
{
int fd = open("temp", O_RDWR | O_CREAT, 0644);
int fd1;
dup2(1, fd1); //fd1保存标准输出文件描述符
dup2(fd, 1); //将标准输出文件描述符1复制为fd,此时1和fd都指向"temp"文件
printf("xixihaha\n");//将该句输出到文件"temp"中
dup2(fd1, 1); //将描述符1改回为标准输出描述符
printf("ooo\n");//这句输出在终端上
return 0;
}
最开始我的思路是这样子的,但是结果缺大相径庭,两条语句都输出在了终端上,没有重定向到文件"temp"中,检查完逻辑关系之后,发现没有什么大问题,那就只有一种可能就是缓冲区的问题了,经过下面这段代码的验证证实了我的想法。
可能进行dup2之后的printf打印的东西不是行缓冲,不是遇到换行符’\n’刷新缓冲区,我的猜想可能是与文件操作相同,用的是全缓冲,只有当写满时才能刷新缓冲区,所以我做了下面这个实验代码
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/types.h>
int main(void)
{
int fd = open("temp", O_RDWR | O_CREAT, 0644); //打开一个文件
int fd1;
dup2(1, fd1); //fd1保存标准输出文件描述符
dup2(fd, 1); //将标准输出文件描述符1复制为fd,此时1和fd都指向"temp"文件
printf("xixihaha\n"); //将该句输出到文件"temp"中
fflush(stdout); //清空缓冲区
dup2(fd1, 1); //将描述符1改回为标准输出描述符
printf("ooo\n"); //这句输出在终端上
close(fd1);
return 0;
}
这个时候输出的结果就是我们想要的结果了,fflush强行将输出缓冲区进行刷新。然后将打印的结果重定向到了文件中。所以验证了我之前的猜想,与缓冲区有关系。