如何進(jìn)行dup和dup2函數(shù)的重定向與還原-創(chuàng)新互聯(lián)

今天就跟大家聊聊有關(guān)如何進(jìn)行dup和dup2函數(shù)的重定向與還原,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

創(chuàng)新互聯(lián)是一家專注于網(wǎng)站制作、成都網(wǎng)站建設(shè)與策劃設(shè)計(jì),鼓樓網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:鼓樓等地區(qū)。鼓樓做網(wǎng)站價(jià)格咨詢:18982081108

在說重點(diǎn)之前我們先來看看dup 和 dup2 函數(shù)的用法

dup 和 dup2 都是系統(tǒng)調(diào)用,都可以用來復(fù)制文件描述符


#include <unistd.h>

int dup(int oldfd);

復(fù)制一個(gè)老的文件描述符,返回新的文件描述符,且這兩個(gè)文件描述符共享同一個(gè)文件指針,指向同一個(gè)文件。

默認(rèn)文件描述符返回的是沒有使用的且最小的。


int dup2(int oldfd, int newfd);

和dup 一樣, 只不過自己指定了新的文件描述符。

調(diào)用成功,返回新的文件描述符。

shell 中的重定向 “ < ”  (輸入)  和 “ > ”(輸出)就是用 dup 函數(shù)實(shí)現(xiàn)的。


我們來看一段代碼。

#include <stdio.h>

#include <unistd.h>

#include <sys/stat.h>

#include <fcntl.h>

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

{

        int oldfd;

       

        oldfd = open("a.txt", O_RDWR | O_CREAT | O_APPEND , 0666);    //打開文件

       if(old == -1)

       {

               printf("creation file failed\n");

               exit(-1);

       }

       else

       {

               dup2(oldfd , 1);      //

               printf("重定向成功\n");

        }

        close(oldfd);

    
        return 0;

}

     


運(yùn)行結(jié)果是在a.txt 里面輸出“ 重定向成功 ” 這幾個(gè)字。

那么現(xiàn)在按照我們自己的理解來分析一下

一個(gè)文件描述符對(duì)應(yīng)一個(gè)文件指針從而對(duì)應(yīng)一個(gè)文件,首先文件描述符 1 對(duì)應(yīng)輸出設(shè)備(默認(rèn)為終端),而新創(chuàng)建的

a.txt 返回的文件描述符,我們假定滿足一定的條件為 3


所以我們記作:

1     -->     終端

3     -->     a.txt

當(dāng)我們使用dup 以后結(jié)果

1     -->      a.txt


3     -->      a.txt

可以看出 dup 函數(shù)說是復(fù)制一個(gè)文件描述符, 自己理解的花話也可以說成是替換了其中一個(gè)文件描述符的指向。1 原本指向終端,現(xiàn)在指向a.txt, 那么原本輸出到終端的內(nèi)容不就輸出到a.txt了嗎。

這樣就完成了“ 重定向 ”功能。

問題出來了

按照上面的代碼,重定向完卻并沒有恢復(fù),文件指針還是指向代碼中的a.txt,我們接著執(zhí)行程序,輸出依然會(huì)在a.txt里面,除非你調(diào)用exit()或者其他的函數(shù)提前結(jié)束進(jìn)程。

那么如果我們想還原呢?

首先我們要定義save_fd 用來保存我們將要覆蓋掉的終端的文件描述符

1     -->    終端

3     -->    a.txt

4     -->    終端      文件描述符4 為save_fd。

我們已經(jīng)讓一個(gè)新的文件描述符指向了終端,那么接下來我們可以放心大膽的改變指向了。

1     -->    a.txt

3     -->    a.txt

4     -->    終端

在完成重定向以后

加上 dup2(save_fd, 1);

文件描述符 1 的指向變成了 save_fd 的指向,也就是還原到了最開始指向了終端,所以可以繼續(xù)在終端下輸出了。

1      -->   終端

3      -->   a.txt

接著我們關(guān)閉這個(gè)臨時(shí)“ 存儲(chǔ)器 ”。


close (save_fd);

這樣就完成了重定向外加恢復(fù)。

然而在實(shí)踐中我又出現(xiàn)了一些小問題

請(qǐng)看部分代碼

oldfd = open("a.txt", O_CREAT | O_APPEND | O_RDWR, 0666);   //打開文件


save_fd = dup(1);   //保存終端的文件描述符


dup2(oldfd ,1);       //重定向到a.txt


printf("重定向成功\n");

dup2(save_fd, 1);      //重定向到終端,也就是還原到終端


close(save_fd);    //關(guān)閉

然而我在輸出時(shí),“ 重定向成功 ”這幾個(gè)字并沒有輸出到a.txt, 而是依然輸出到了屏幕上,

我覺得代碼和邏輯都不應(yīng)該錯(cuò)啊,最后找了一會(huì)發(fā)現(xiàn)了問題,我用write函數(shù)寫就能寫到 a.txt里面,用printf輸出卻輸出不到 a.txt 里面,最后我在printf()后面加了一個(gè)清空緩沖區(qū)函數(shù)fflush(stdout)就完美的解決了問題,這么說就是緩沖區(qū)的問題了,今天的重點(diǎn)也不是緩沖區(qū),而且我也不是那么了解- - 。

我又做了實(shí)驗(yàn),將fflush(stdout)放到了printf()前面,輸出結(jié)果卻依然是不對(duì)的。

那么我大膽猜測(cè):

當(dāng)我們重定向完成后,輸出會(huì)輸出到a.txt也就是指定的文件里,然而printf()函數(shù)輸出是先到達(dá)緩沖區(qū),我們也知道緩沖區(qū)是有大小的,所以也要等待緩沖區(qū)填滿才開始向外“ 拿 ”,然而在我這個(gè)例子中,還沒來得及從緩沖區(qū)取數(shù)據(jù),重定向就復(fù)原了,所以依然輸出到了屏幕上。這也是我們需要小心謹(jǐn)慎的地方。

補(bǔ)充:dup也可以重定向到網(wǎng)絡(luò)的socket文件描述符,和管道


看完上述內(nèi)容,你們對(duì)如何進(jìn)行dup和dup2函數(shù)的重定向與還原有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。

當(dāng)前標(biāo)題:如何進(jìn)行dup和dup2函數(shù)的重定向與還原-創(chuàng)新互聯(lián)
本文URL:http://www.muchs.cn/article26/dhjejg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、Google、建站公司、標(biāo)簽優(yōu)化、靜態(tài)網(wǎng)站、網(wǎng)站內(nèi)鏈

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司