1 文件管理的相關函數
open close write read lseek 調整文件的讀寫位置
1.1 標C文件處理和UC文件處理函數的比較
根據程序的結構可知,標C的文件處理函數比UC的文件處理函數速度快,因為標C函數內部都有輸入輸出緩沖區,會積累一定數量之後再寫入文件,因此讀寫的效率比較高,使用 time 命令來查看程序運行的時間。
real 真實時間 user 用戶態時間 sys 內核態時間;
注意
對於UC的文件處理函數來講,可以通過自定義緩沖區來提高讀寫的效率。
1.2 文件描述符
i節點編號,是硬盤文件位置的唯一標識。i節點之前V節點主要包含V節點信息,i節點信息,用來維護i節點的信息,v節點之前存在文件表,主要是文件的標識信息,第二部分是文件的讀寫位置,第三部分是v節點指針。進程中包括文件描述符,文件表指針,文件描述符用來對應文件表指針,
文件描述符就是一個整數,可以代表一個打開的文件,但是文件的信息不是存在一個文件描述符之中,而是在文件表等結構中,當打開一個文件時候,系統會把文件信息存入文件表等結構中,但是出於安全考慮,文件表等結構不能直接操作,而是給文件表對應一個編號,我們用編號進行操作,標號就是文件描述符。
在進程內部,維護著一張文件描述符的總表,當使用open 函數打開文件時候,就會加載該文件的信息到內存中,然後去文件描述符的總表中查找一個最小的未被使用的描述符建立和文件表的對應關系,而文件描述符是一個非負整數,從0開始一直到 OPEN_MAX在linux 中一般書255 ,其中012 被系統占用,分別代表標准輸入,標准輸出個標准錯誤,
close 函數的工作方式: 表示先把對應關系從文件描述符總表中刪除,不一定會刪除文件表,只有當文件表不會和任何其他文件描述符有對應關系時候(也就是文件表可以對應多個文件描述符),才會刪除文件表,也就是說close函數不會改變文件描述符的整數值,只是會讓該描述符無法代表一個文件
在同一個進程或者不同的進程,多次打開同一個文件的時候,文件表會產生多個,但是v節點只有一個。
1.3 dup/dup2/函數
#icnlude
int dup(int oldfd);
函數功能
根據參數指定的文件描述符進行復制,成功返回新的文件描述符,失敗返回-1;
使用完這個函數之後,要使用close 進行關閉文件。使用這個函數之後生成的文件描述符和原來的文件描述符所對應的是同一個文件表。
int dup(int oldfd,int newfd);
主要用於將 oldfd 參數指定的文件表地址拷貝到newfd中,如果newfd 被占用則關閉,成功返回新的文件描述符,失敗返回-1;
注意 :
dup/dup2函數用於賦值文件描述符時候,實質上是文件描述符所對應的文件表地址,也就是讓多個文件描述符對應同一個表,從而對應同一個文件。
1.4 fcntl 函數 (重點 復雜)
#include
#include
int fcntl(int fd,int cmd,...);
fd 文件描述符
cmd 命令操作 執行什麼操作,函數的主要作用就是根據cmd 進行操作,
1 F_DUPFD 復制文件描述符,新的文件描述符會選擇大於等於arg 的值作為參數fd 的備份。不會強制關閉正在使用的描述符。
2 F_GETFD/F_SETFD - 獲取和設置文件描述符標志
3 F_GETFL/F_SETFL 獲取和設置文件的狀態標注
4 F_GETLK/F_SETLK/F_SETLKW 增加釋放和判斷鎖是否存在。
可變長參數 是否需要取決於第二個
返回值
F_DUPFD 成功返回新的文件描述符,失敗返回-1;
F_GETFD/SETFD 成功返回獲取標志 0 失敗返回-1;
F_GETFL/F_SETFL 成功返回0,失敗返回-1;
F_SET/F_SETLKW/F_GETLK 成功返回0;失敗返回-1;
函數功能:
1 主要是用來復制文件描述符
2 設置/獲取文件描述符的功能
3 設置獲取文件狀態標志的功能
4 實現建議型文件鎖的功能(要求掌握)
1.5 使用fcntl實現文件鎖的功能
1 文件鎖的作用
當有多個進程同時對一個共享文件進行讀寫操作時候,可能對數據造成混亂和不一致性,理論上要求多個進程對文件操作進行串行不是並行。如果兩個進程都是讀取文件則允許同同時進行,只要有一個寫操作,另外一個進程應該等待,為了實現這個功能,需要借助文件鎖。
文件鎖就是讀寫鎖,也就是一把讀鎖和一鎖把寫鎖,其中讀是一把共享鎖,不允許其他進程加寫鎖。可以加讀鎖,而寫鎖是一把互斥鎖,不允許其他進程加讀鎖和寫鎖。
2 實現文件鎖的功能,fcntl函數的cmd 參數F_SETLK/F_SETLKW/F_GETLK
第三個參數的取值
是一個指向一下結構體類型的指針。結構體是
struct flock
{
short l_type; 鎖的類型 讀鎖寫鎖解鎖
short l_whence;起始位置
off_t l_start; 偏移的字節
off_t l_len; 枷鎖的字節數
pid_t l_pid; 加鎖的進程號
}
3 F_SETLK 主要用於加鎖或者解鎖
發現 對文件進行加寫鎖之後,還是可以向文件進行加入數據內容的,也就是文件鎖是獨立於文件的,並沒有真正鎖定對文件的讀寫操作,也就是文件鎖只能用於鎖定其他的鎖。(導致第二次加鎖失敗,兩個讀鎖除外)
問題:考慮如何使用文件鎖來控制文件的讀寫操作。
解決方案 :
一般來說可以在進行讀寫操作之前嘗試加讀寫鎖,根據能否加讀寫鎖來判斷是否進行讀寫操作。
釋放鎖的方法
1 進程結束自動釋放所有文件鎖。
2 把的類型改成 F_UNLCK 然後使用fcntl重新設置即可;