在linux系統中把設備和普通文件也都看做是文件,要對文件進行操作就必須先打開文件,打開文件后會得到一個文件描述符,它是一個很小的正整數,是一個索引值。
內核會為每一個運行中的進程在進程控制塊pcb中維護一個打開文件的記錄表,每一個表項都有一個指針指向打開的文件,上邊的索引值是記錄表的索引值。
文件描述符的優點:兼容POSIX標准,許多系統調用都依賴於它;缺點是不能移植到unix之外的系統上去。
文件指針:c語言中使用的是文件指針而不是文件描述符來作為I/O的句柄,文件指針指向進程的用戶空間中一個FILE結構的數據結構,FILE結構里主要包括一個I/O緩沖區和一個文件描述符,而文件描述符值是文件描述符表中的一個索引,從某種意義上將文件指針就是句柄的句柄(在Window中文件描述符被稱為文件句柄)。
文件指針的優點:是c語言中的通用格式,便於移植。
既然FILE結構中含有文件描述符,那么可以使用fopen來獲得文件指針,然后從文件指針獲取文件描述符,文件描述符應該是唯一的,而文件指針卻不是唯一的,但指向的對象是唯一的。
C語言文件指針域文件描述符之間可以相互轉換
int fileno(FILE * stream)
FILE * fdopen(int fd, const char * mode)
FILE的結構
struct _iobuf {
char *_ptr; //緩沖區當前指針
int _cnt;
char *_base; //緩沖區基址
int _flag; //文件讀寫模式
int _file; //文件描述符
int _charbuf; //緩沖區剩余自己個數
int _bufsiz; //緩沖區大小
char *_tmpfname;
};
typedef struct _iobuf FILE;
open和fopen的區別
| open | fopen |
|----------------------------+----------------------------- |
| open返回一個文件描述符 | 返回FILE * |
| 無緩沖 | 有緩沖 |
| 與write()和read()配合使用 | 與fwrite()和fread()配合使用 |
int fd = open("TAGS", O_RDONLY);
FILE * fp = fopen("TAGS", "r");
printf("%d %d\n", fd, fp->_file);
可以從文件指針中獲取文件描述符
fileno(fp) 和fp->_file效果是一樣的
FILE * fp = fdopen(fd, "r") 根據文件描述符加上訪問模式可以得到文件指針