物联网学习教程-Linux系统编程之文件描述符的复制:dup()和dup2()

246 阅读3分钟

    Linux系统编程之文件描述符的复制:dup()和dup2()

  dup()和dup2()是两个非常有用的系统调用,都是用来复制一个文件的描述符,使新的文件描述符也标识旧的文件描述符所标识的文件。

  这个过程类似于现实生活中的配钥匙,钥匙相当于文件描述符,锁相当于文件,本来一个钥匙开一把锁,相当于,一个文件描述符对应一个文件,现在,我们去配钥匙,通过旧的钥匙复制了一把新的钥匙,这样的话,旧的钥匙和新的钥匙都能开启这把锁。对比于dup(),dup2()也一样,通过原来的文件描述符复制出一个新的文件描述符,这样的话,原来的文件描述符和新的文件描述符都指向同一个文件,我们操作这两个文件描述符的任何一个,都能操作它所对应的文件。

  所需头文件:

  #include<unistd.h>

  int dup(int oldfd);

  功能:

  通过oldfd复制出一个新的文件描述符,新的文件描述符是调用进程文件描述符表中最小可用的文件描述符,最终oldfd和新的文件描述符都指向同一个文件。

  参数:

  oldfd:需要复制的文件描述符oldfd

  返回值:

  成功:新文件描述符

  失败:-1

  dup实例:

  下面的例子为,打开一个文件得到文件描述符,并复制该文件描述符,通过这2个描述符分别对此文件进行写

  #include<stdio.h>

  #include<unistd.h>

  #include<stdlib.h>

  #include<sys/types.h>

  #include<sys/stat.h>

  #include<fcntl.h>

  #include<string.h>

  int main(int argc,char*argv[])

  {

  int fd1=0;

  int fd2=0;

  //打开文件

  fd1=open("test.txt",O_CREAT|O_WRONLY,0666);

  if(fd1<0){

  perror("open");

  exit(-1);

  }

  printf("fd1==============%d\n",fd1);

  //通过fd1复制出fd2,最终fd1,fd2都指向test.txt

  fd2=dup(fd1);

  printf("fd2==============%d\n",fd2);

  char*buf1="this is a test for fd1\n";

  //操作fd1文件描述符

  write(fd1,buf1,strlen(buf1));

  char*buf2="this is a test for fd2\n";

  //操作fd2文件描述符

  write(fd2,buf2,strlen(buf2));

  //关闭文件描述符,两个都得关

  close(fd1);

  close(fd2);

  return 0;

  }

  运行结果:   

  接下来,我们继续一起学习dup2()的用法,功能和dup()完全一样,但是dup2()复制出来的新文件描述符可以指定任意一个合法的数字

  int dup2(int oldfd,int newfd);

  功能:

  通过oldfd复制出一个新的文件描述符newfd,如果成功,newfd和函数返回值是同一个返回值,最终oldfd和新的文件描述符newfd都指向同一个文件。

  参数:

  oldfd:需要复制的文件描述符

  newfd:新的文件描述符,这个描述符可以人为指定一个合法数字(0-1023),如果指定的数子已经被占用(和某个文件有关联),此函数会自动关闭close()断开这个数字和某个文件的关联,再来使用这个合法数字。

  返回值:

  成功:返回newfd

  失败:返回-1

  接着,我们将上面的例子改为用dup2()来实现:

  #include<stdio.h>

  #include<unistd.h>

  #include<stdlib.h>

  #include<sys/types.h>

  #include<sys/stat.h>

  #include<fcntl.h>

  int main(int argc,char*argv[])

  {

  int fd1;

  int fd2;

  //打开文件

  fd1=open("test.txt",O_CREAT|O_WRONLY,0666);

  if(fd1<0){

  perror("open");

  exit(-1);

  }

  printf("fd1==============%d\n",fd1);

  //通过fd1复制出fd2,最终fd1,fd2都指向“1.txt”

  //指定fd2的值为1,1原来指向标准输出设备,先close(),再复制

  fd2=dup2(fd1,1);

  //下面这句话的内容不会打印到屏幕上,而会写到文件“1.txt”里

  //printf()是标准库函数,最终还是会调用系统调用函数write()

  //相当于这样,write(1,),往1文件描述符写内容,

  //默认的情况下,1文件描述符指向标准输出设备(如,显示屏)

  //所以,printf()的内容先显示到屏幕上

  //但是现在1文件描述符指向文件“1.txt”

  //所以,printf()的内容会写入文件“1.txt”

  printf("fd2==============%d\n",fd2);

  close(fd1);

  close(fd2);

  return 0;

  }

  运行结果: