文件描述符

內(nèi)核(kernel)利用文件描述符(file descriptor)來(lái)訪問(wèn)文件债蜜。文件描述符是非負(fù)整數(shù)崔涂。打開現(xiàn)存文件或新建文件時(shí)漩怎,內(nèi)核會(huì)返回一個(gè)文件描述符趣竣。讀寫文件也需要使用文件描述符來(lái)指定待讀寫的文件。

文件描述符在形式上是一個(gè)非負(fù)整數(shù)胆剧。實(shí)際上絮姆,它是一個(gè)索引值,指向內(nèi)核為每一個(gè)進(jìn)程所維護(hù)的該進(jìn)程打開文件的記錄表秩霍。當(dāng)程序打開一個(gè)現(xiàn)有文件或者創(chuàng)建一個(gè)新文件時(shí)篙悯,內(nèi)核向進(jìn)程返回一個(gè)文件描述符。在程序設(shè)計(jì)中铃绒,一些涉及底層的程序編寫往往會(huì)圍繞著文件描述符展開鸽照。但是文件描述符這一概念往往只適用于UNIXLinux這樣的操作系統(tǒng)颠悬。[1]

習(xí)慣上矮燎,標(biāo)準(zhǔn)輸入(standard input)的文件描述符是 0,標(biāo)準(zhǔn)輸出(standard output)是 1赔癌,標(biāo)準(zhǔn)錯(cuò)誤(standard error)是 2诞外。盡管這種習(xí)慣并非Unix內(nèi)核的特性,但是因?yàn)橐恍?shell 和很多應(yīng)用程序都使用這種習(xí)慣灾票,因此峡谊,如果內(nèi)核不遵循這種習(xí)慣的話,很多應(yīng)用程序?qū)⒉荒苁褂谩?/p>

POSIX 定義了 STDIN_FILENO刊苍、STDOUT_FILENO 和 STDERR_FILENO 來(lái)代替 0既们、1、2班缰。這三個(gè)符號(hào)常量的定義位于頭文件 unistd.h贤壁。

文件描述符的有效范圍是 0 到 OPEN_MAX。一般來(lái)說(shuō)埠忘,每個(gè)進(jìn)程最多可以打開 64 個(gè)文件(0 — 63)脾拆。對(duì)于 FreeBSD 5.2.1馒索、Mac OS X 10.3 和 Solaris 9 來(lái)說(shuō),每個(gè)進(jìn)程最多可以打開文件的多少取決于系統(tǒng)內(nèi)存的大小名船,int 的大小绰上,以及系統(tǒng)管理員設(shè)定的限制。Linux 2.4.22 強(qiáng)制規(guī)定最多不能超過(guò) 1,048,576 渠驼。

文件描述符是由無(wú)符號(hào)整數(shù)表示的句柄蜈块,進(jìn)程使用它來(lái)標(biāo)識(shí)打開的文件。文件描述符與包括相關(guān)信息(如文件的打開模式迷扇、文件的位置類型百揭、文件的初始類型等)的文件對(duì)象相關(guān)聯(lián),這些信息被稱作文件的上下文蜓席。

如何創(chuàng)建文件描述符

進(jìn)程獲取文件描述符最常見的方法是通過(guò)本機(jī)子例程open或create獲取或者通過(guò)從父進(jìn)程繼承器一。后一種方法允許子進(jìn)程同樣能夠訪問(wèn)由父進(jìn)程使用的文件。文件描述符對(duì)于每個(gè)進(jìn)程一般是唯一的厨内。當(dāng)用fork子例程創(chuàng)建某個(gè)子進(jìn)程時(shí)祈秕,該子進(jìn)程會(huì)獲得其父進(jìn)程所有文件描述符的副本,這些文件描述符在執(zhí)行fork時(shí)打開雏胃。在由fcntl请毛、dup和dup2子例程復(fù)制或拷貝某個(gè)進(jìn)程時(shí),會(huì)發(fā)生同樣的復(fù)制過(guò)程瞭亮。

對(duì)于每個(gè)進(jìn)程方仿,操作系統(tǒng)內(nèi)核在u_block結(jié)構(gòu)中維護(hù)文件描述符表,所有的文件描述符都在該表中建立索引街州。

特點(diǎn)

編輯

優(yōu)點(diǎn)

文件描述符的好處主要有兩個(gè):

基于文件描述符的I/O操作兼容POSIX標(biāo)準(zhǔn)兼丰。

UNIXLinux系統(tǒng)調(diào)用中唆缴,大量的系統(tǒng)調(diào)用都是依賴于文件描述符。

例如,下面的代碼就示范了如何基于文件描述符來(lái)讀取當(dāng)前目錄下的一個(gè)指定文件黍翎,并把文件內(nèi)容打印至Console中面徽。

此外,在Linux系列的操作系統(tǒng)上匣掸,由于Linux的設(shè)計(jì)思想便是把一切設(shè)備都視作文件趟紊。因此,文件描述符為在該系列平臺(tái)上進(jìn)行設(shè)備相關(guān)的編程實(shí)際上提供了一個(gè)統(tǒng)一的方法碰酝。

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <sys/types.h>

#include

#include <fcntl.h>

int main(void){ int fd; int numbytes; char path[] = "file"; char buf[256]; /*

* O_CREAT: 如果文件不存在則創(chuàng)建

* O_RDONLY:以只讀模式打開文件

*/

fd = open(path, O_CREAT | O_RDONLY, 0644);

if(fd < 0){ perror("open()");

exit(EXIT_FAILURE); } memset(buf, 0x00, 256);

while((numbytes = read(fd, buf, 255)) > 0){ printf("%d bytes read: %s", numbytes, buf);

memset(buf, 0x00, 256);

} close(fd);

exit(EXIT_SUCCESS);}

缺點(diǎn)

文件描述符的概念存在兩大缺點(diǎn):

在非UNIX/Linux操作系統(tǒng)上(如Windows NT)霎匈,無(wú)法基于這一概念進(jìn)行編程。

由于文件描述符在形式上不過(guò)是個(gè)整數(shù)送爸,當(dāng)代碼量增大時(shí)铛嘱,會(huì)使編程者難以分清哪些整數(shù)意味著數(shù)據(jù)暖释,哪些意味著文件描述符。因此墨吓,完成的代碼可讀性也就會(huì)變得很差球匕。

定義數(shù)量

編輯

如何在不同平臺(tái)上定義文件描述符的數(shù)量

文件描述符極限以及可分配給進(jìn)程的最大大小由資源限制來(lái)定義。這些值應(yīng)當(dāng)按照在WebLogicServer文檔中建議的帖烘、特定于操作系統(tǒng)的文件描述符值來(lái)設(shè)置:

對(duì)于WLS8.1:調(diào)整硬件亮曹、操作系統(tǒng)和網(wǎng)絡(luò)性能

對(duì)于WLS7.0:調(diào)整硬件、操作系統(tǒng)和網(wǎng)絡(luò)性能

對(duì)于WLS6.1:調(diào)整硬件秘症、操作系統(tǒng)和網(wǎng)絡(luò)性能

Unix和Linux都有文件描述符照卦。不過(guò),二者的主要區(qū)別在于如何設(shè)置文件描述符的硬極限值乡摹、缺省值和配置過(guò)程役耕。

Solaris

/usr/bin/ulimit實(shí)用程序定義允許單個(gè)進(jìn)程使用的文件描述符的數(shù)量。它的最大值在rlim_fd_max中定義趟卸,在缺省情況下蹄葱,它設(shè)置為65,536。只有root用戶才能修改這些內(nèi)核值锄列。

Linux

管理用戶可以在etc/security/limits.conf配置文件中設(shè)置他們的文件描述符極限图云,如下例所示。

softnofile1024

hardnofile4096

系統(tǒng)級(jí)文件描述符極限還可以通過(guò)將以下三行添加到/etc/rc.d/rc.local啟動(dòng)腳本中來(lái)設(shè)置:

#Increasesystem-widefiledescriptorlimit.

echo4096>/proc/sys/fs/file-max

echo16384>/proc/sys/fs/inode-max

Windows

在Windows操作系統(tǒng)上邻邮,文件描述符被稱作文件句柄竣况。在Windows2000服務(wù)器上,打開文件的句柄極限設(shè)置為16,384筒严。此數(shù)量可以在任務(wù)管理器的性能摘要中監(jiān)視丹泉。

HP-UX

nfile定義打開文件的最大數(shù)量。此值通常由以下公式來(lái)確定:

((NPROC*2)+1000)鸭蛙,其中NPROC通常為:((MAXUSERS*5)+64)摹恨。如果MAXUSERS等于400,則經(jīng)過(guò)計(jì)算得到此值為

5128娶视。通成购澹可以將此值設(shè)高一些。maxfiles是每個(gè)進(jìn)程的軟文件極限肪获,maxfiles_lim是每個(gè)進(jìn)程的硬文件極限寝凌。

AIX

文件描述符極限在/etc/security/limits文件中設(shè)置,它的缺省值是2000孝赫。此極限可以通過(guò)ulimit命令或setrlimit子例程來(lái)更改较木。最大大小由OPEN_MAX常數(shù)來(lái)定義。

解決方法

編輯

對(duì)于ANSI C規(guī)范中定義的標(biāo)準(zhǔn)庫(kù)的文件I/O操作青柄。ANSI C規(guī)范給出了一個(gè)解決方法伐债,就是使用FILE結(jié)構(gòu)體指針预侯。事實(shí)上,UNIX/Linux平臺(tái)上的FILE結(jié)構(gòu)體的實(shí)現(xiàn)中往往都是封裝了文件描述符變量在其中泳赋。

在UNIX/Linux平臺(tái)上雌桑,對(duì)于控制臺(tái)(Console)的標(biāo)準(zhǔn)輸

入,標(biāo)準(zhǔn)輸出祖今,標(biāo)準(zhǔn)錯(cuò)誤輸出也對(duì)應(yīng)了三個(gè)文件描述符校坑。它們分別是0,1,2。在實(shí)際編程中千诬,如果要操作這三個(gè)文件描述符時(shí)耍目,建議使

用頭文件中定義的三個(gè)宏來(lái)表示: STDIN_FILENO,

STDOUT_FILENO以及STDERR_FILENO。 與文件描述符相關(guān)的操作

文件描述符的生成

open(), open64(), creat(), creat64()

socket()

socketpair()

pipe()

與單一文件描述符相關(guān)的操作

read(), write()

recv(), send()

recvmsg(),sendmsg()

sendfile()

lseek(), lseek64()

fstat(), fstat64()

fchmod()

fchown()

與復(fù)數(shù)文件描述符相關(guān)的操作

select(), pselect()

poll()

與文件描述符表相關(guān)的操作

close()

dup()

dup2()

fcntl (F_DUPFD)

fcntl (F_GETFD and F_SETFD)

改變進(jìn)程狀態(tài)的操作

fchdir()

mmap()

與文件加鎖的操作

flock()

fcntl (F_GETLK, F_SETLK and F_SETLKW)

lockf()

與套接字相關(guān)的操作

connect()

bind()

listen()

accept()

getsockname()

getpeername()

getsockopt(), setsockopt()

shutdown()

文件描述符與文件指針的區(qū)別

編輯

文件描述符:在linux系統(tǒng)中打開文件就會(huì)獲得文件描述符徐绑,它是個(gè)很小

的正整數(shù)邪驮。每個(gè)進(jìn)程在PCB(Process Control

Block)中保存著一份文件描述符表,文件描述符就是這個(gè)表的索引傲茄,每個(gè)表項(xiàng)都有一個(gè)指向已打開文件的指針毅访。文件指針:C語(yǔ)言中使用文件指針做為I/O

的句柄。文件指針指向進(jìn)程用戶區(qū)中的一個(gè)被稱為FILE結(jié)構(gòu)的數(shù)據(jù)結(jié)構(gòu)盘榨。FILE結(jié)構(gòu)包括一個(gè)緩沖區(qū)和一個(gè)文件描述符喻粹。而文件描述符是文件描述符表的一個(gè)

索引,因此從某種意義上說(shuō)文件指針就是句柄的句柄(在Windows系統(tǒng)上草巡,文件描述符被稱作文件句柄)守呜。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市山憨,隨后出現(xiàn)的幾起案子查乒,更是在濱河造成了極大的恐慌,老刑警劉巖郁竟,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玛迄,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡棚亩,警方通過(guò)查閱死者的電腦和手機(jī)憔晒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蔑舞,“玉大人,你說(shuō)我怎么就攤上這事嘹屯」パ” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵州弟,是天一觀的道長(zhǎng)钧栖。 經(jīng)常有香客問(wèn)我低零,道長(zhǎng),這世上最難降的妖魔是什么拯杠? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任掏婶,我火速辦了婚禮,結(jié)果婚禮上潭陪,老公的妹妹穿的比我還像新娘雄妥。我一直安慰自己,他們只是感情好依溯,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布老厌。 她就那樣靜靜地躺著,像睡著了一般黎炉。 火紅的嫁衣襯著肌膚如雪枝秤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天慷嗜,我揣著相機(jī)與錄音淀弹,去河邊找鬼。 笑死庆械,一個(gè)胖子當(dāng)著我的面吹牛薇溃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播干奢,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼痊焊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了忿峻?” 一聲冷哼從身側(cè)響起薄啥,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎逛尚,沒想到半個(gè)月后垄惧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绰寞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年到逊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滤钱。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡觉壶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出件缸,到底是詐尸還是另有隱情铜靶,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布他炊,位于F島的核電站争剿,受9級(jí)特大地震影響已艰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蚕苇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一哩掺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧涩笤,春花似錦嚼吞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至锰茉,卻和暖如春呢蔫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背飒筑。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工片吊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人协屡。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓俏脊,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親肤晓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子爷贫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 一些概念: 1.為了便于統(tǒng)一管理,系統(tǒng)將所有的輸入/輸出設(shè)備都視為文件补憾,按文件方式提供給用戶使用漫萄,如目錄的檢索、權(quán)...
    yydounai閱讀 1,023評(píng)論 0 4
  • 文件描述符 在Linux中盈匾,進(jìn)程是通過(guò)文件描述符(file descriptors腾务,簡(jiǎn)稱fd)而不是文件名來(lái)訪問(wèn)文...
    德彪閱讀 3,566評(píng)論 0 4
  • 在linux系統(tǒng)中把設(shè)備和普通文件也都看做是文件,要對(duì)文件進(jìn)行操作就必須先打開文件削饵,打開文件后會(huì)得到一個(gè)文件描述符...
    踩在浪花上00閱讀 1,124評(píng)論 0 1
  • 這里以問(wèn)答的方式來(lái)討論這個(gè)問(wèn)題: 1. 文件描述符 fd 和文件指針 FILE *的關(guān)系岩瘦? 文件描述符是什么?我...
    ieasy_tm閱讀 1,615評(píng)論 0 2
  • 理解文件描述符 文件描述符(FileDescriptor) 這是Unix/Linux系統(tǒng)文件操作的相關(guān)概念窿撬,And...
    sugaryaruan閱讀 10,700評(píng)論 1 4