標籤:
首先是常用的幾個函數 open , read,write,lseek, close
open函數 函數原型 int open(char * path,int oflag,...) 傳回值是一個檔案描述符 path顧名思義就是檔案名稱 oflage檔案是開啟檔案 第三個形參應用於建立檔案時使用 /*建立檔案其實還有一個create函數使用 以及openat由於還未使用過這個函數和open的差異 所以不在此處累贅*/ open函數 使用if 判斷的時候 注意小細節
read函數 函數原型 ssize_t read(int fd , void* buf , size_t nbytes) 傳回值是檔案讀取位元組數 在好幾種情況下會出現傳回值不等於檔案讀取位元組數 也就是第三個參數nbytes的情況 第二個形參buf讀取到buf的記憶體 檔案位移量(current file offset)受改變
write函數 函數原型 ssize_t write(int fd , const void* buf, size_t nbytes) 傳回值是檔案寫入位元組數 fd是檔案描述符 將buf內容寫入nbytes個位元組到檔案 但這裡需要注意預設情況是需要在系統隊列中等待寫入(開啟檔案不同也會不同) //以上三個出錯都返回-1
lseek函數off_t lseek(int fd, off_t offset , int whence) 傳回值成功函數返回新的檔案位移量 失敗-1 fd檔案描述符 off_t是有符號的整數 whence其實是和off_t配套使用的 SEEK_SET檔案開始處 SEEK_CUR當前值的相對位置 SEEK_END檔案長度+-
close函數原型 int close(int fd) 傳回值 成功返回0 失敗—1 關閉檔案描述符
下面就有倆個重要的概念 一個是核心用三種資料結構來表示開啟檔案 另一個也和它有原因就是檔案io的原子性
由於在linux環境下沒有畫圖的軟體 就加以簡單描述三種檔案狀態資料結構 第一個是檔案描述符fd的描述(我懶沒查 我更喜歡知道原理 用的時候再查細節 = =!!)第二個是檔案表項 第三個是v節點 第一個第二個是呈鏈表狀
然後檔案表項指向v節點 不同的fd檔案描述符訪問同一檔案就是訪問不同的fd指向同一個v節點
1 struct Fd{ 2 int fd; //檔案描述符 3 void* filePtr; //檔案指標指向檔案表 4 }; 5 6 7 struct FileTable{ 8 int fileMark; // 檔案狀態標誌 9 off_t offset; //檔案位移量10 void* vNode; 11 }12 //其實還有第三個的 我沒學到所以也就不害人了
看完上面這個很破很破的代碼(命名沒有大寫)的時候你應該發現一個問題了如果兩個線程訪問同一檔案 會產生一個操作異常其實就是各自的的檔案表項的資料非同步造成的 可能會造成覆蓋另一條進程的資料 這裡就體現了原子操作的必要性了 它的意思就是所有操作會一次性完成作業系統不會只執行一半就去執行另一條進程了
fcntl函數 int fcntl(int fd , int cmd,...) 這個函數可以改變已經開啟檔案的屬性 但是要注意必須先獲得目前的標誌值 然後再設定 上code 應用於一個以建立檔案以唯讀開啟 使用fcntl修改開啟狀態寫入文本
1 #include<apue.h>
2 #include<fcntl.h>
3 void set_fl(int fd, int flags) // flags are file status to ture on
4 {
5 int val ;
6 if((val = fcntl(fd,F_GETFL, 0)) < 0){
7 printf("err -1!");
8 err_sys("fcntl get error!");
9 }
10 val |= flags;
11 if( fcntl( fd , F_SETFL , val) < 0){
12 printf("error 0!");
13 err_sys("fcontl set error!");
14 }
15
16 }
17
18 int main(void)
19 {
20 int fd = 0;
21 char buf[] = "xiaochen";
22
23 if((fd = open("aa.txt" , O_WRONLY )) < 0){
24 printf("err 1!");
25 err_sys("open error!");
26 }
27 set_fl(fd,O_WRONLY);
28 if(write(fd , buf , 8) != 8 ){
29 printf(" err 2!");
30 err_sys("write error");
31 }
32
33 close(fd);
34 return 0;
35
36 }
~
~
由於只是總結不做太多細節描述
完。。。。 //書讀少了好多都只知道概念 上面函數都有簡單的小demo 我比較懶破代碼就不show了 學完一章做個小總結還是很有用的 如果您有一天看見這篇破文章有學習上的問題或者發現博文裡我的錯誤 請聯絡我很會非常感謝您 qq:1639153000
關於unix系統介面 普通檔案io的小結