1. 檔案描述符
- unix 系統 shell 把檔案描述符 0 與程序的標準輸入關聯,檔案描述符 1 與標準輸出關聯,檔案描述符 2 與標準錯誤關聯;
- 上述 0、1、2 使用時應該替換為符號常量 stdin_fileno、stdout_fileno 和 stderr_fileno;
- 檔案描述符的變化范文是 0 ~ open_max - 1;
2. open 和 openat
- 原型:
int open(const char *path, int oflag, …);
int openat(int fd, const char *path, int oflag, …);
- path 引數是要開啟或建立檔案的名字;
- oflag引數可用來說明此函式的多個選項(oflag引數之間用 「|」 連線);
- open 和 openat 返回的檔案描述符一定是最小的未用描述符數值;
- fd 引數:
1) path引數指定的是絕對路徑名,fd被忽略,此時倆原型一樣;
2) path引數指定的是相對路徑名,fd引數表示相對路徑名在檔案系統中的開始位址;
3) path引數指定的是相對路徑名,fd引數具有特殊值at fdcwd,此時,路徑名在當前工作目錄中獲取;
3. 函式creat
- 原型:
int creat(const char *path, mode_t mode);//成功返回檔案描述符,失敗返回-1
open(path, o_wronly | o_creat | o_trunc, mode);
4. 函式 close
- 原型:
int close (int fd);
- 當乙個程序終止時,核心自動關閉它所有的開啟檔案。
5. 函式 lseek
- 原型:
off_t lseek(int fd, off_t offset, int whence);//成功返回新的檔案偏移量,失敗返回-1;
- 功能:顯式地為乙個開啟檔案設定偏移量;
- 引數whence:
1) 若whence為seek_set,則偏移量為距檔案開始處offset個位元組;
2) 若whence為seek_cur,則偏移量為其當前值加offset,offset可正可負;
3) 若whence為seek_end,則偏移量為檔案長度加offset,offset可正可負;
- 確定開啟檔案的當前偏移量的方式(也可用來確定所涉及的檔案是否可以設定偏移量):
off_t currpos;
currpos = lseek(fd, 0, seek_cur);
- 通常情況下,對於普通檔案來講,偏移量必須是非負值。但由於有些檔案允許偏移量為負,所以在判斷偏移量是否設定成功時,我們需要判斷的是返回值是否等於-1,而非是否小於零。
- 空洞:當檔案的偏移量大於檔案的當前長度,下一次的寫操作將加長該檔案,並在檔案中構成乙個空洞。我的理解是「先占個地」,也就是用空洞來佔位置,保證下一次寫入是在我們預期的地方。另外,空洞檔案可以用來保證多執行緒的順利進行,因為這個「佔位置」的作用,使同乙個任務可以分段寫入。
6. 函式 read
- 原型:
ssize_t read ( int fd, void *buf, size_t bnytes);//返回值為讀到的位元組數,若到檔案尾,返回零,出錯返回-1;
7. 函式 write
- 原型:
ssize_t write ( int fd, const void *buf, size_t bnytes);//成功返回已寫位元組數,出錯返回-1
8. 核心用三種資料結構表示開啟檔案
1) 每個程序在程序表中有乙個記錄項,記錄項中包含一張開啟檔案描述符表;
2) 核心為所有開啟檔案維持一張檔案表;
3) 每個開啟檔案都有乙個v節點(v-node)結構,v 節點包含了檔案型別和對此檔案進行各種操作函式的指標。(linux中使用的是i節點,概念相同)
9. 原子操作
- 所謂原子操作,指的是乙個操作或者乙個操作集合,該操作要麼執行完,要麼不執行;
- 原子操作能夠有效避免很多操作間的衝突,比如對檔案的修改,如果兩個程序對乙個檔案同時進行操作,或者操作時間差不太多,很有可能出現前乙個程序的操作被強行覆蓋掉,或者偏移量已經被另乙個程序修改之類的錯誤。
- 函式 pread = lseek + read;但 pread 就是原子操作,一旦呼叫,無法中斷,並且 pread 不更新當前檔案偏移量。( pwrite 同理)
10. 函式 dup 和 dup2
- 原型:
int dup ( int fd);
int dup2 ( int fd, int fd2 );
- 作用:複製乙個現有的檔案描述符;
- dup 返回的是當前可用檔案描述符中的最小數值,而 dup2 可以給定新的描述符的值;
- 如果 fd2 已經被占用,則先關閉 fd2(dup2是原子操作,而且可以關別的檔案,感覺有點強勢);
11. 延遲寫
- 延遲寫,就是建立乙個緩衝區,把寫入資料儲存到一定程度,一次性寫入,避免過於頻繁的呼叫i/o(類似於printf的輸出緩衝區);
- sync 函式:將所有修改過的塊緩衝區排入寫佇列,然後返回;
- fsync 函式:只對fd指定的乙個檔案起作用,並且等到磁碟操作結束才返回;
- fdatasync 函式:同 fsync ,但只影響資料,不同步更新檔案屬性。
12. 函式 fcntl
- 功能:
1) 複製乙個已有的描述符;
2) 獲取/設定檔案描述符標誌;
3) 獲取/設定檔案狀態標誌;
4) 獲取/設定非同步i/o所有權;
5) 獲取/設定記錄鎖;
- 注:修改檔案描述符標誌或檔案狀態標誌時,先要獲得現在的標誌值,然後修改,最後設定新的標誌值。否則會關閉以前設定的標誌位。
13. /dev/fd
- 開啟 /dev/fd/n 相當於複製描述符 n。
第三章 檔案I O
include int open const char pathname,int oflag,mode t mode 成功返回檔案描述符,出錯返回 1 oflag 可多選 o rdonly 唯讀 o wronly 只寫 o rdwr 讀 寫 mode o creat 檔案不存在則建立 o excl ...
第三章 檔案I O
include include off t lseek int fileds,off t offset,int whence 成功返回新檔案的位移量,失敗返回 1 返回值可能為負數,所有測試它的返回值時應該確定是否為 1而不是是否為負數。stdin 屬於標準庫處理的輸入流,其宣告為 file 型的,...
APUE 第三章 檔案I O
linux對檔案操作有open read write close lseek,這些api都是不帶緩衝的函式,相對於c庫,這些可移植的api內部實現是有緩衝區的。int open char pathname,int flag,int read int fd,void buf,size t size i...