fd是在檔案io中貫穿始終的型別
1、檔案描述符的概念(整形數 陣列下標 檔案描述符優先使用當前可用範圍內最小的 作用域:當前程序)
2、檔案io操作:open close read write lseek
1>開啟乙個檔案:int open(const char *pathname, int flags, ...);
返回值:成功,返回檔案描述符; 出錯, 返回-1.
pathname引數是要開啟或建立檔案的名字,flags引數:o_rdonly 唯讀開啟
o_wronly 只寫開啟
o_rdwr 讀、寫開啟
......
2>關閉乙個檔案:int close(int fd);
返回值:成功,返回0; 出錯, 返回-1.
關閉乙個檔案時還會釋放該程序加在該檔案上的所有記錄鎖.
3>讀乙個檔案: ssize_t read(int fd, void *buf, size_t nbytes);
返回值:讀到的位元組數,若已到檔案尾,返回0, 出錯,返回-1.
fd表示讀取那個檔案, buf表示讀取的位元組放到buf中, nbytes表示讀取的位元組數.
4>寫乙個檔案: ssize_t write(int fd, const void *buf, size_t nbytes);
返回值:成功,返回已寫的位元組數, 出錯,返回-1.
fd表示要寫入的那個檔案, buf表示從buf中的內容讀到fd當中, nbytes表示寫入的位元組數.
5>定位乙個檔案: off_t lseek(int fd, off_t offset, int whence);
返回值:成功,返回新的檔案偏移量; 出錯,返回-1.
引數fd表示要操作的檔案,offset表示為偏移量,whence表示參照物(從**開始)
whence:seek_set 偏移量設定為距檔案開始處offset個位元組;
seek_cur 偏移量設定為當前值加offset個位元組,offset可正可負;
seek_end 偏移量設定為檔案長度加offset個位元組,offset可正可負。
沒有單位的數值沒有意義。
注意:od -c 檢視檔案中的空洞,ll -s 檢視檔案長度,du –s 檢視檔案占用磁大小
注意:當用 read 讀 stdin_fileno 時候,如果要讀的字元數為 x,終端中有字元 y 個,
如果 x>=y,那麼 read 會讀到 y 個字元,如果 x
3、檔案io與標準io的區別
區別:響應速度&吞吐量
檔案io 標準io
面試:如何使乙個程式變快?
使用者體驗上是吞吐量。
轉換:fileno fdpoen
atrace ./ab 跟蹤乙個檔案執行過程。
4、io的效率問題
習題:將mycpy.c程式進行更改,將bufsize的值進行放大,並觀察程序所消耗的時間,
注意效能最佳拐點出現時的bufsize值,以及何時程式會出現問題。
5、檔案共享:多個任務共同操作乙個檔案或者協同完成任務
面試:寫程式刪除乙個檔案的第10行
補充函式:truncate/ftruncate.
6、原子操作:不可分割的單位
原子:不可分割的最小單位
作用:解決競爭和衝突
如tmpnam建立臨時檔案
7、程式中的重定向:dup dup2
1>複製乙個現有檔案描述符: int dup(int oldfd);
返回值:成功,返回新的檔案描述符; 出錯,返回-1.
複製後兩個檔案描述符指向同乙個檔案表項(struct file 結構體)實現檔案的共享,同時寫乙個檔案時是接續寫.
2>複製乙個新的描述符newfd: int dup2(int oldfd, int newfd);
返回值:成功,返回新的檔案描述符; 出錯,返回-1.
注意:返回的新描述符一定是當前可用的檔案描述符的最小值;
注意:如果 newfd 已經被開啟則會先關閉newfd(解除檔案描述符與檔案表項的鏈結),如果 newfd 和 oldfd 相等則該函式什麼都不做;
注意:新描述符和舊的描述符各有自己的檔案描述符標誌,新檔案描述符的 fd_cloexec標誌被清除。
注意:交叉寫入時是接續寫。
8、同步 sync fsync fdatasync
檔案同步
把所有修改過的檔案塊刷到核心的寫佇列,並不等待真正的寫到磁碟
針對核心
void sync(void);
和 sync 一樣,不過這個函式只是針對於特定檔案
void syncfs(int fd);
把 fd 描述檔案的內容都刷到磁碟之後才返回
int fsync(int fd);
返回值:成功,返回0; 失敗, 返回-1.
和 fsync 一樣,不過這個函式只是重新整理檔案的資料部分,屬性部分並不會因這個函式而重新整理
int fdatasync(int fd);
返回值:成功,返回0; 失敗, 返回-1.
9、函式 fcntl 和 ioctl
改變已經開啟檔案的屬性:int fcntl(int fd, int cmd, ... /* arg */ );
這個函式可以改變/獲取乙個檔案的檔案描述符標誌和檔案狀態標誌
返回值:成功, 則依賴於cmd; 出錯, 返回-1。
引數1表示要操作那個檔案, 引數2表示要進行那個操作命令。
檔案描述符標誌:
現在的系統就乙個 o_cloexec,如果乙個檔案描述符標誌中沒有設定 o_cloexec,那麼在 exec 乙個新程式的時候這個檔案描述符依然有效,
否則這個檔案描述符在 exec 的時候是關閉的,dup(2)複製的新檔案描述符總是被清除 fd_cloexec 標誌.
在用 fcntl 設定檔案狀態許可權是不能設定檔案訪問許可權和檔案建立的許可權的,
比如 o_rdonly, o_wronly, o_rdwr,o_creat, o_excl, o_trunc。
複製檔案描述符:cmd=f_dupfd/f_dupfd_cloexec
int ioctl(int fd, int request, ...);
注意:這個和函式和底層的具體實現有關係
返回值:出錯,返回-1; 成功,返回其他值。
10、/dev/fd/目錄:虛目錄 顯示的是當前程序的檔案描述符資訊.
APUE 學習筆記 二 檔案I O
對於核心而言,所有開啟的檔案都通過檔案描述符引用,核心不區分文字檔案和二進位制檔案 open函式 o rdonly o wronly o rdwr create函式 close函式 關閉乙個檔案時還會釋放該程序加在該檔案上的所有記錄鎖 lseek函式 顯式地為乙個開啟的檔案設定其偏移量 每個開啟的檔...
《APUE》筆記(1) 檔案I O
1 概述 1 unix類作業系統最重要的兩個東東 程序和檔案 2 大多數檔案i o用到的5個函式 open,close,read,write,lseek.還有檔案屬性操作函式 dup,fcntl 3 unix類作業系統的檔案i o是不帶快取的i o unbuffered i o 2 檔案描述符 fi...
APUE學習筆記 檔案IO
1 lseek的返回值應該判斷是否為0,而不是小於0。2 偏移量可以大於檔案大小。這個時候會有檔案空洞。4 open加上標誌 o create和o excl可以判斷檔案是否存在。5 dup和dup2可複製檔案描述符。並可指定複製後的描述符。6 linux ext2檔案系統不支援o sync標誌。可以...