【轉】Linux系統編程---dup和dup2詳解
正常的文件描述符:
在linux下,通過open打開以文件後,會返回一個文件描述符,文件描述符會指向一個文件表,文件表中的節點指針會指向節點表。看下圖:
dup和dup2兩個函數都可以用來復制打開的文件描述符,復制成功後和復制源共享同一個文件表。看下圖:
(1)dup函數
fd1=dup(fd);
fd1和fd共享一個文件表(對fd進行什麽操作,fd1也會有相應的操作,fd和fd1是同步的)。
具體解釋:
#inclue<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
int main()
{
char buf[6]={0};
char buf1[6]={0};
int fd = open("file",O_RDWR|O_CREAT,0644);
if(fd < 0)
printf("open error");
printf("fd:%d\n",fd);
//輸出fd=3;
write(fd,"hello,world",12);
lseek(fd,0,SEEK_SET); //將文件偏移量置為0,就是從第一個字符開始讀(h開始)
read(fd,buf,5);
printf("fd:%s",buf);//輸出hello
int fd1 = dup(fd);
read(fd1,buf1,5); //之前做的是對fd的讀寫操作,並沒有對fd1做任何操作。但在這對fd1進行了讀,如果輸出數據。說明fd和fd1是同步的(fd做了什麽相當於fd1也做了什麽)
printf("fd1:%s\n",buf1); //輸出,worl
//既然輸出的是fd中的內容,說明fd和fd1共用一個文件表,讀到的是,worl,而不是hello(我們在上面將偏移量從第一個字符開始,輸出hello之後,fd的偏移量距離開始有5個字符當我們再次讀fd的時候,它是從第6個字符開始讀的,很明顯,第6個是逗號,往後讀5個,就是,worl),說明偏移量是一致的。(其實不用寫偏移量,因為共用文件表就意味著文件偏移量也共用)
printf("fd1:%d\n",fd1);//輸出fd1 = 4
//fd=3不等於fd1說明不共用同一個文件描述符。這也是dup和dup2的區別。
close(fd);
close(fd1);
return 0;
}
(2)dup2函數
fd2 = dup2(fd,fd1);
fd2用的fd1(第二個參數)的描述符,用的fd(第一個參數)的文件(和fd共享一個文件表,當然也共享文件偏移量)
強調第幾個參數是因為如果你寫成fd2=dup2(fd1,fd);那麽fd2 =fd,和fd1共享同一個文件表。
#inclue<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
int main()
{
int fd = open("file",O_RDWR|O_CREAT,0644);
if(fd < 0)
printf("open error");
printf("fd:%d\n",fd);
//輸出fd=3;
int fd1 =open("text",,O_RDWR|O_CREAT,0644);
if(fd1 < 0)
printf("open error");
printf("fd1:%d\n",fd1);
//輸出fd1=4;
int fd2 = dup2(fd,fd1);
printf("fd2:%d\n",fd2);
//輸出fd2=4;
//fd1 =fd2=4;說明fd2使用了fd1的文件描述符。
char buf[12]="hello,world";
write(fd,buf,12); //我們對fd進行了寫,並沒有對fd2進行寫
read(fd2,buf,12);//但是我們對fd2讀的時候,如果沒有寫,怎麽可能讀出來呢
printf("fd2:%s\n",buf);//事實是讀出來了
//輸出fd2:hello,world //說明fd和fd2共用一個文件表。
lseek(fd,5,SEEK_SET);//距離開始偏移5位,說明下次讀的時候是從第6個開始,註意我們是對fd進行偏移,沒有對fd2偏移
read(fd2,buf,5); //但是如果讀fd2結果是從第6個字符開始的
buf[5]=0; //如果不寫這句,輸出的buf是按照12個字符輸出的。因為定義buf的時候數組中可以放12個字符。
printf("fd2:%s\n",buf);//輸出fd2:,worl //說明fd2和fd共享文件偏移量。
close(fd);
close(fd2);
return 0;
}
dup和dup2的區別
dup:fd1= dup(fd);目標描述符使用了fd的文件表
dup2:fd2 = dup2(fd1,fd)目標描述符使用了fd1的描述符,使用了fd的文件表
【轉】Linux系統編程---dup和dup2詳解