檔案流和檔案描述符

2021-08-29 01:40:25 字數 2623 閱讀 4945

檔案流和檔案描述符

檔案流和 檔案描述符

2011-10-19 16:08

apue 中的一道課後題:

習題8.1

#include"apue.h"

int glob=6;

int main(void)

else if(pid==0)

i = printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);

sprintf(buf, "%d\n", i);

write(stdout_fileno, buf, strlen(buf));

exit(0);

}程式的執行結果如下:

$ ./a.out

before vfork

-1stdin是標準輸入檔案,stdout是標準輸出檔案,stderr標準出錯檔案,應用在輸出的重新定位上。

程式按如下方式使用這些檔案:

標準輸入 是程式可以讀取其輸入的位置。預設情況下,程序從鍵盤讀取 stdin 。

標準輸出 是程式寫入其輸出的位置。預設情況下,程序將 stdout 寫到終端螢幕上。

標準錯誤 是程式寫入其錯誤訊息的位置。預設情況下,程序將 stderr 寫到終端螢幕上。

檔案描述符:如果我們用fd表示,該fd可以是open、pipe、dup、dup2和creat等呼叫返回的結果,在linux系統中,裝置也是以檔案的形式存在,要對該裝置進行操作就必須先開啟這個檔案,開啟這個檔案就會,就會獲得這個檔案描述符,它是個很小的正整數,它是乙個索引值,指向核心為每乙個程序所維護的該程序開啟檔案的記錄表。檔案描述符的優點:相容posix標準,許多linux和 unix系統呼叫都依賴於它。檔案描述符的缺點:不能移植到unix以外的系統上去,也不直觀。

fd只是乙個索引.

檔案指標: c語言中使用的是檔案指標而不是檔案描述符做為i/o的控制代碼."檔案指標(file pointer)"指向程序使用者區中的乙個被稱為file結構的資料結構。file結構包括乙個緩衝區和乙個檔案描述符值.而檔案描述符值是檔案描述符表中的乙個索引.從某種意義上說檔案指標就是控制代碼的控制代碼。

用下面的流圖可以說明問題: (ps: 雖然不是流圖關係,但是還是有助於理解)

printf -> stdout -> stdout_fileno(1) -> 終端(tty)

stdout/stdin -- 標準輸出輸入裝置 (printf("..")) 。

stderr -- 標準錯誤輸出裝置

兩者預設向螢幕輸出。

但如果用轉向標準輸出到磁碟檔案,則可看出兩者區別。stdout輸出到磁碟檔案,stderr在螢幕。

printf最後的輸出到了終端裝置,檔案描述符1指向當前的終端可以這麼理解:

stdout_fileno = open("/dev/tty", o_rdwr);

stdout/stdin型別為 file*

stdout_fileno型別為 int

使用stdout/stdin的函式主要有:fread、fwrite、fclose等,基本上都以f開頭

使用stdin_fileno的函式有:read、write、close等

fwrite(buf,strlen(buf), 1,stdout);

write(stdout_fileno,&buf,strlen(buf));

總結:注釋(1)的fclose 只關閉了stdout,而沒有關閉stdout_fileno,所以write() 仍然可以寫到stdout_fileno中.

但是把(1)處改為close(stdout_fileno),程式輸出變為:

./a.out

before vfork

pid = 28003, glob = 7, var = 89

32 檔案描述符和檔案流之間的轉換

file *fdopen(int fildes, const char *type);

這個函式很有用的,功能是將乙個流關聯到乙個開啟的檔案號filedes上,

該filedes可以是open、pipe、dup、dup2和creat等呼叫返回的結果

type指定流開啟方式,同fopen的開啟方式,如"a", "r","w"等等

fdopen的流開啟方式服從filedes的開啟方式,比如filedes的open指定o_rdonly,那麼fdopen也只能指定"r"的開啟方式了。

用fdopen的好處很明顯,如果你不得已只能開啟檔案號,比如socket或者dup呼叫,但又想用fprintf,fscanf等流操作來進行讀寫,那麼就再fdopen一次好了。

int fileno(file stream);

用 fileno有什麼好處呢?你用fopen開啟了檔案,但是又想用flock或者lockf來給檔案加鎖,或者用fcntl來進行某些底層的操作,但上述這些函式只能對開啟的檔案號操作,而不能對開啟流,這時候就用fileno再flock、lockf、fcntl好了。

二進位制i/o

但是對於結構體的流讀寫用這些是不合適的,因為null的原因,其中讀寫結構體的函式為下

fread ,fwrite,相關文件以後再附上 

主意:經常出現這種情況:在乙個系統環境上寫,在另乙個環境上讀取,函式是不能正常工作的,可能情況如下:

1:同一成員的位移量可能隨操作環境編譯環境的不同而不同

2:二進位制格式的不同

檔案流和 檔案描述符

include apue.h int glob 6 int main void else if pid 0 i printf pid d,glob d,var d n getpid glob,var sprintf buf,d n i write stdout fileno,buf,strlen b...

檔案指標和檔案描述符

原文 檔案描述符 在linux系統中,裝置也是以檔案的形式存在,要對該裝置進行操作就必須先開啟這個檔案,開啟檔案就會獲得檔案描述符,它是個很小的正整數。每個程序在pcb process control block 中儲存著乙份檔案描述符表,檔案描述符就是這個表的索引,每個表項都有乙個指向已開啟檔案的...

檔案指標和檔案描述符

檔案描述符 在linux系統中,裝置也是以檔案的形式存在,要對該裝置進行操作就必須先開啟這個檔案,開啟檔案就會獲得檔案描述符,它是個很小的正整數。每個程序在pcb process control block 中儲存著乙份檔案描述符表,檔案描述符就是這個表的索引,每個表項都有乙個指向已開啟檔案的指標。...