最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux中文件描述符fd與文件指針FILE*互相轉(zhuǎn)換實(shí)例解析

 更新時(shí)間:2018年01月29日 10:33:27   作者:Harley_Quinn  
這篇文章主要介紹了Linux中文件描述符fd與文件指針FILE*互相轉(zhuǎn)換實(shí)例解析,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下

本文研究的主要是Linux中文件描述符fd與文件指針FILE*互相轉(zhuǎn)換的相關(guān)內(nèi)容,具體介紹如下。

1.文件描述符fd的定義:文件描述符在形式上是一個(gè)非負(fù)整數(shù)。實(shí)際上,它是一個(gè)索引值,指向內(nèi)核為每一個(gè)進(jìn)程所維護(hù)的該進(jìn)程打開(kāi)文件的記錄表。當(dāng)程序打開(kāi)一個(gè)現(xiàn)有文件或者創(chuàng)建一個(gè)新文件時(shí),內(nèi)核向進(jìn)程返回一個(gè)文件描述符。在程序設(shè)計(jì)中,一些涉及底層的程序編寫(xiě)往往會(huì)圍繞著文件描述符展開(kāi)。但是文件描述符這一概念往往只適用于UNIX、Linux這樣的操作系統(tǒng)。

2.文件指針FILE定義說(shuō)明文件指針的一般形式為:

FILE *指針變量標(biāo)識(shí)符;

其中FILE應(yīng)為大寫(xiě),它實(shí)際上是由系統(tǒng)定義的一個(gè)結(jié)構(gòu),該結(jié)構(gòu)中含有文件名、文件狀態(tài)和文件當(dāng)前位置等信息。在編寫(xiě)源程序時(shí)不必關(guān)心FILE結(jié)構(gòu)的細(xì)節(jié)。

使用系統(tǒng)調(diào)用的時(shí)候用文件描述符的時(shí)候比較多,但是操作比較原始。C庫(kù)函數(shù)在I/O上提供了一些方便的包裝(比如格式化I/O、重定向),但是對(duì)細(xì)節(jié)的控制不夠。

如果過(guò)度依賴(lài)其中的一種只會(huì)徒增麻煩,所以知道兩者的轉(zhuǎn)換是很有必要的。FILE*是對(duì)fd的封裝

當(dāng)然,有人會(huì)說(shuō)知道文件路徑的話(huà)重新打開(kāi)就是了,但是這會(huì)產(chǎn)生競(jìng)爭(zhēng)條件(Race Conditions),首先重新打開(kāi)文件,相當(dāng)于是2個(gè)fd指向同一文件,然后如果在打開(kāi)的期間文件被刪除了又被新建了一個(gè)同名文件,2個(gè)fd指向的便是不同的文件。

glibc庫(kù)提供了兩個(gè)轉(zhuǎn)換函數(shù)fdopen(3)和fileno(3),都是<stdio.h>中的

FILE *fdopen(int fd, const char *mode);
int fileno(FILE *stream);

PS:為了節(jié)省篇幅,還是繼續(xù)忽略返回值的檢查。

來(lái)看看測(cè)試吧,是不是我們想的那樣。

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main()
{
  const char* filename = "new.txt";
  int fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

  FILE* fp = fdopen(fd, "w+");
  int fd2 = fileno(fp);

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

  fclose(fp);
  close(fd);
  return 0;
}
$ gcc test.c 
$ ./a.out 
fd=3 | fd2=3

參考fileno手冊(cè):

The function fileno() examines the argument stream and returns its integer descriptor.

FILE是對(duì)fd的封裝,fileno()是直接取得被封裝的fd,因此并未創(chuàng)建新的fd指向該文件。

參考fdopen手冊(cè):

The fdopen() function associates a stream with the existing file descriptor, fd. The mode of
the stream (one of the values "r", "r+", "w", "w+", "a", "a+") must be compatible with the
mode of the file descriptor.

fdopen()是講流(FILE對(duì)象)與已存在的文件描述符fd進(jìn)行關(guān)聯(lián),因此也是未創(chuàng)建新的fd。值得注意的是,F(xiàn)ILE指針的模式(mode)必須與文件描述符的模式兼容。

關(guān)于mode參數(shù)先擱置會(huì)兒,目前我們知道的是,使用fileno和fdopen進(jìn)行轉(zhuǎn)換,都是在原有的fd上進(jìn)行操作,并未產(chǎn)生新的fd。那么,再次審視剛才的代碼,是否發(fā)現(xiàn)了問(wèn)題?

我們來(lái)檢查下close(fd)的返回值,把close(fd)改成下列代碼

  if (-1 == close(fd)) {
    perror("close");
    exit(1);
  }
$ gcc test.c 
$ ./a.out 
close: Bad file descriptor

沒(méi)錯(cuò),fclose在關(guān)閉文件指針的時(shí)候,內(nèi)部其實(shí)也關(guān)閉了文件描述符(否則資源就泄露了),既然這里fp內(nèi)部的文件描述符和fd是同一個(gè),當(dāng)fp被關(guān)閉時(shí),fd也被關(guān)閉了,再次關(guān)閉fd就會(huì)出現(xiàn)“損壞的文件描述符”錯(cuò)誤。

OK,現(xiàn)在回顧下fopen的第2個(gè)參數(shù),又r/r+/w/w+/a/a+一共6種設(shè)置(windows平臺(tái)的rb/rb+/wb/wb+暫且不談),對(duì)比Linux手冊(cè)我將對(duì)應(yīng)的open設(shè)置列出來(lái)

依然是進(jìn)行測(cè)試,修改fd_mode和fp_mode,看看實(shí)驗(yàn)結(jié)果

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

const int security = S_IRUSR | S_IWUSR;
const int fd_mode = O_RDWR | O_CREAT | O_TRUNC;
const char* fp_mode = "r";

int main()
{
  int fd = open("new.txt", fd_mode, security);
  FILE* fp = fdopen(fd, fp_mode);
  if (fp == NULL) {
    perror("fdopen");
    exit(1);
  }

  close(fd);
  return 0;
}

在fd_mode等價(jià)于"w+"時(shí),fp_mode的6種設(shè)置(r/r+/w/w+/a/a+)均返回非空指針。

在fd_mode等價(jià)于"w"時(shí),fp_mode6種設(shè)置只有"a"和"w"返回非空指針。

繼續(xù)嘗試"r"/"r+"/"a"/"a+"的設(shè)置,可以發(fā)現(xiàn)所謂“兼容”只與讀寫(xiě)權(quán)限有關(guān),O_RDWR兼容O_RDONLY和O_WRONLY,而后兩者則只與自身兼容。

有意思的是O_APPEND(在末尾添加)和O_TRUNC(截?cái)辔募念^添加)也兼容。

The file position indicator of the new stream is set to that
belonging to fd, and the error and end-of-file indicators are cleared. Modes "w" or "w+" do
not cause truncation of the file. The file descriptor is not dup'ed, and will be closed when
the stream created by fdopen() is closed.

繼續(xù)查看fdopen的手冊(cè)內(nèi)容,可以看到"w"和"w+"在這里不會(huì)導(dǎo)致文件截?cái)唷?/p>

后一句也印證了我們前面的實(shí)驗(yàn)結(jié)果:文件描述符不會(huì)被復(fù)制,文件指針被關(guān)閉時(shí)文件描述符也會(huì)被關(guān)閉。

PS:其實(shí)fdopen的手冊(cè)上還有最后一句:The result of applying fdopen() to a shared memory object is undefined.

將fdopen用于共享內(nèi)存對(duì)象的結(jié)果是未定義的。

總結(jié)

以上就是本文關(guān)于Linux中文件描述符fd與文件指針FILE*互相轉(zhuǎn)換實(shí)例解析的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專(zhuān)題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!

相關(guān)文章

  • linux userdel 命令的使用

    linux userdel 命令的使用

    這篇文章主要介紹了linux userdel 命令的使用,幫助大家更好的理解和使用Linux系統(tǒng),感興趣的朋友可以了解下
    2020-08-08
  • Apache加速模塊mod_pagespeed安裝使用詳細(xì)介紹

    Apache加速模塊mod_pagespeed安裝使用詳細(xì)介紹

    這篇文章主要介紹了Apache加速模塊mod_pagespeed安裝使用詳細(xì)介紹,需要的朋友可以參考下
    2014-03-03
  • 如何在linux服務(wù)器上使用tensorboard

    如何在linux服務(wù)器上使用tensorboard

    這篇文章主要介紹了如何在linux服務(wù)器上使用tensorboard,包括錯(cuò)誤記錄,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • linux之source.list的使用解析

    linux之source.list的使用解析

    /etc/apt/source.list文件定義了軟件源的相關(guān)信息,包括檔案類(lèi)型、倉(cāng)庫(kù)地址和版本代號(hào),倉(cāng)庫(kù)地址指向了軟件包的索引文件和具體存放路徑,修改該文件后需要更新軟件包列表,才能安裝新的軟件
    2025-03-03
  • hadoop基于Linux7的安裝配置圖文詳解

    hadoop基于Linux7的安裝配置圖文詳解

    這篇文章主要介紹了hadoop基于Linux7的安裝配置,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • linux系統(tǒng)下oracle11gR2靜默安裝的經(jīng)驗(yàn)分享

    linux系統(tǒng)下oracle11gR2靜默安裝的經(jīng)驗(yàn)分享

    這篇文章主要介紹了linux系統(tǒng)下oracle11gR2靜默安裝的經(jīng)驗(yàn), 所有操作無(wú)需使用圖形界面. 靜默安裝能減少安裝出錯(cuò)的可能性, 也能大大加快安裝速度。有需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-01-01
  • 阿里云服務(wù)器ping不通解決辦法(云服務(wù)器搭建完環(huán)境訪(fǎng)問(wèn)不了ip解決辦法)

    阿里云服務(wù)器ping不通解決辦法(云服務(wù)器搭建完環(huán)境訪(fǎng)問(wèn)不了ip解決辦法)

    這篇文章主要介紹了阿里云服務(wù)器ping不通解決辦法(云服務(wù)器搭建完環(huán)境訪(fǎng)問(wèn)不了ip解決辦法),文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2007-05-05
  • 讓Apache 2支持.htaccess并實(shí)現(xiàn)目錄加密的方法

    讓Apache 2支持.htaccess并實(shí)現(xiàn)目錄加密的方法

    這篇文章主要介紹了讓Apache 2支持.htaccess并實(shí)現(xiàn)目錄加密的方法,文中給出了詳細(xì)的方法步驟,并給出了示例代碼,對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-02-02
  • Vim中文件編碼處理與重新打開(kāi)亂碼文件詳解

    Vim中文件編碼處理與重新打開(kāi)亂碼文件詳解

    這篇文章主要給大家介紹了關(guān)于Vim中文件編碼處理與重新打開(kāi)亂碼文件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-04-04
  • crontab執(zhí)行結(jié)果未通過(guò)發(fā)送mail通知用戶(hù)的方法

    crontab執(zhí)行結(jié)果未通過(guò)發(fā)送mail通知用戶(hù)的方法

    這篇文章主要給大家介紹了關(guān)于crontab執(zhí)行結(jié)果未通過(guò)發(fā)送mail通知用戶(hù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用linux系統(tǒng)具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06

最新評(píng)論

镶黄旗| 玛曲县| 遂平县| 鹤山市| 奈曼旗| 武乡县| 宁波市| 延吉市| 汤原县| 虎林市| 德州市| 孝义市| 茶陵县| 浑源县| 都兰县| 成都市| 涞源县| 商丘市| 永德县| 鹿泉市| 邵东县| 隆德县| 融水| 鹤壁市| 宁蒗| 满城县| 偏关县| 瑞安市| 方正县| 扎鲁特旗| 灵丘县| 阳谷县| 莆田市| 射阳县| 双鸭山市| 枣阳市| 栖霞市| 温州市| 叶城县| 临湘市| 延吉市|