国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

Linux中文件描述符fd與文件指針FILE*互相轉換實例解析

2024-08-28 00:03:46
字體:
來源:轉載
供稿:網友

本文研究的主要是Linux中文件描述符fd與文件指針FILE*互相轉換的相關內容,具體介紹如下。

1.文件描述符fd的定義:文件描述符在形式上是一個非負整數。實際上,它是一個索引值,指向內核為每一個進程所維護的該進程打開文件的記錄表。當程序打開一個現有文件或者創建一個新文件時,內核向進程返回一個文件描述符。在程序設計中,一些涉及底層的程序編寫往往會圍繞著文件描述符展開。但是文件描述符這一概念往往只適用于UNIX、Linux這樣的操作系統。

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

FILE *指針變量標識符;

其中FILE應為大寫,它實際上是由系統定義的一個結構,該結構中含有文件名、文件狀態和文件當前位置等信息。在編寫源程序時不必關心FILE結構的細節。

使用系統調用的時候用文件描述符的時候比較多,但是操作比較原始。C庫函數在I/O上提供了一些方便的包裝(比如格式化I/O、重定向),但是對細節的控制不夠。

如果過度依賴其中的一種只會徒增麻煩,所以知道兩者的轉換是很有必要的。FILE*是對fd的封裝

當然,有人會說知道文件路徑的話重新打開就是了,但是這會產生競爭條件(Race Conditions),首先重新打開文件,相當于是2個fd指向同一文件,然后如果在打開的期間文件被刪除了又被新建了一個同名文件,2個fd指向的便是不同的文件。

glibc庫提供了兩個轉換函數fdopen(3)和fileno(3),都是<stdio.h>中的

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

PS:為了節省篇幅,還是繼續忽略返回值的檢查。

來看看測試吧,是不是我們想的那樣。

#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手冊:

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

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

參考fdopen手冊:

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對象)與已存在的文件描述符fd進行關聯,因此也是未創建新的fd。值得注意的是,FILE指針的模式(mode)必須與文件描述符的模式兼容。

關于mode參數先擱置會兒,目前我們知道的是,使用fileno和fdopen進行轉換,都是在原有的fd上進行操作,并未產生新的fd。那么,再次審視剛才的代碼,是否發現了問題?

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

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

沒錯,fclose在關閉文件指針的時候,內部其實也關閉了文件描述符(否則資源就泄露了),既然這里fp內部的文件描述符和fd是同一個,當fp被關閉時,fd也被關閉了,再次關閉fd就會出現“損壞的文件描述符”錯誤。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 建平县| 利川市| 黄浦区| 阿拉善右旗| 灵宝市| 崇明县| 香港| 浠水县| 井研县| 乌鲁木齐市| 沈阳市| 北安市| 新巴尔虎左旗| 石屏县| 衡阳市| 榆中县| 彭阳县| 静乐县| 梓潼县| 噶尔县| 安西县| 榆中县| 普安县| 耒阳市| 桦甸市| 太原市| 教育| 青神县| 玉环县| 岫岩| 乌兰浩特市| 泽库县| 土默特右旗| 乳源| 托克逊县| 永泰县| 濉溪县| 宁德市| 庄浪县| 肃宁县| 成都市|