物聯網學習教程Linux系統程式設計之檔案描述符的複製:dup()和dup2()

千鋒教育官方發表於2019-08-15

       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;

}

 

執行結果:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69914734/viewspace-2653773/,如需轉載,請註明出處,否則將追究法律責任。

相關文章