Unix环境高级编程学习笔记(一)
第二章 文件I/O
1、文件描述符
? 對于內核而言,所有打開的文件都通過文件描述符引用,文件描述符是一個非負整數。
? Unix shell使用文件描述符0表示標準輸入,1表示標準輸出,2表示標準出錯輸出,為了避免在代碼中出現魔數,在<unixtd.h>頭文件中,1,2,3替換為符號常量STDIN_FILENO,STDOUT_FILENO,STDERR_FILENO,文件描述符的變化范圍是0~OPEN_MAX。
2、open函數
原型:#include<fcntl.h>
??? int open(const char *pathname, int oflag, ...)?? /*僅當創建新文件時才使用第三個參數*/
?pathname是要打開或創建的文件名字,oflag是參數選項,可選值有:O_RDONLY(只讀打開,0),O_WRONLY(只寫打開,1),O_RDWR(讀寫打開,2),這些常量定義在<fcntl.h>頭文件中,這3個常量必須指定一個且只能指定一個。下列常量是可選的,O_APPEND(寫時追加尾部),O_CREAT(若不存在則創建,需指定第三個參數說明文件訪問權限),O_EXCL(若和O_CREAT一起使用,當要創建的文件已經存在就會失敗),O_TRUNC(文件截短為0,需文件存在,且為只寫或讀寫打開),O_NOCTTY(pathname指向終端設備,不將它作為控制終端),O_NONBLOCK(pathname指向FIFO、塊或字符特殊文件時,設置非阻塞模式)、O_DSYNC(使每次write等待物理IO操作完成,不包括文件屬性IO的更新),O_RSYNC(讀操作等待寫操作完成)、O_SYNC(每次write等待物理IO操作完成,包括文件屬性IO的更新)???? 注意:Linux將O_DSYNC、O_RSYNC、O_SYNC等同與O_SYNC(其實這些知識點應該是自己做實驗發現,而不是等著書本來教你~~)????????????? 返回最小的未使用描述符數值。
3、creat函數
原型:#include<fcntl.h>
??? int create(const char* pathname, mode_t mode);等效于open(pathname, O_WRONLY|O_CREAT|O_TRUNC, mode),可以完全用open函數取代creat函數
4、close函數
原型:#include<unistd.h>
??? int close(int filedes);關閉一個文件時還會釋放該進程加在該文件上的記錄鎖。
5、lseek函數
作用:顯示的為一個文件設置偏移量
原型:#include<unistd.h>
???? off_t lseek(int fileds, off_t offset, int whence);
? 對offset的解釋與whence的值有關,當whence為SEEK_SET,則該文件的偏移量為距文件開頭處offset字節處; 當whence為SEEK_CUR,則該文件的偏移量為當前值加上offset,offset可以為正或負;? 當whence為SEEK_END,則文件偏移量為文件長度加offset,offset可以為正或負。????? 返回新的文件偏移量。
應用:1、確定打開文件當前偏移量:off_t currpos;?????? currpos = lseek(fd, 0, SEEK_CUR);
???? 2、確定所涉及的文件是否可以設置偏移量。如果文件描述符引用的是一個管道、FIFO或網絡套接字,則lseek返回-1,并將errno設置為ESPIPE。
???? 3、lseek允許定位到文件長度之后,這樣就會造成文件空洞。使用od(1)命令可以觀察文件的實際內容。
6、read函數
原型:#include<unistd.h>
???? ssize_t read(int filedes, void *buf, size_t nbytes);???成功返回讀到的字節數,到文件尾返回0,失敗返回-1
7、write函數
原型:#include<unistd.h>
???? ssize write(int filedes, const void* buf, size_t nbytes);???成功返回已寫字節數,若出錯返回-1
8、關于文件共享
?內核使用3種數據結構表示打開的文件:(1)每個進程都有一個打開文件描述符表;(2)內核為所有打開文件維持一張文件表(每個表項包括文件狀態標志,當前文件偏移量,指向該節點v節點指針),(3)一個v節點結構包括文件類型及i節點信息(如文件所有者、文件長度、文件所在設備等等)???????????????? 注:linux沒有v節點,使用的就是i節點
9、使用原子操作的場合:1)、lseek+write -> 使用O_APPEND標志 或 使用pread函數和pwrite函數
10、dup和dup2函數:用于復制一個現存的文件描述符
原型:#include<unistd.h>??? int dup(int filedes);????? int dup2(int filedes1, int filedes2);??? dup返回當前可用的最小文件描述符,dup2可用filedes2指定文件描述符,如果filedes已經打開則先將其關閉,這些函數返回的新文件描述符與filedes共享同一個個文件描述符。
11、sync、fsync、fdatasync函數
?文件io的傳統實現使用延遲寫策略,增加了性能卻降低了文件跟新速度,這3個函數的作用就是保證磁盤里實際的文件內容和緩沖區里內容一致。?? 注意:系統會周期的自動調用sync函數。
原型:#include<unistd.h>??? int fsync(int filedes);??? int fdatasync(int filedes);???? void sync(void);
12、fcntl函數:可以改變已打開文件的性質。
原型:#include<fcntl.h>??????? int fcntl(int filedes, int cmd, ...)???? 出錯返回-1
功能:(1)、復制現有文件描述符(cmd=F_DUPFD)??? (2)、獲得設置文件描述符標志(cmd=F_GETFD或cmd=F_SETFD)? (3)、獲得或設置文件狀態標志(cmd=F_GETFL或cmd=F_SETFL)?? (4)、獲得設置異步IO所有權(cmd=F_GETOWN或F_SETOWN)?? (5)、獲得設置記錄鎖(cmd=F_GETLK、F_SETLK、F_SETLKW)
注意:dup(filedes);等價于fcntl(filedes, F_DUPFD, 0);???????? dup2(filedes1, filedes2);等價于close(filedes2);??? fcntl(filedes1, F_DUPFD, filedes2);
13、ioctl函數:是IO操作的雜物箱,不能用本章中其他函數表示的IO操作通常都能用ioctl表示。
原型:#include<unistd.h>?? #include<sys/ioctl.h>???? #include<stropts.h>
int? ioctl(int filedes, int request, ...)???????? 若出錯,返回-1
14、/dev/fd:該目錄下為Linux打開文件描述符的映射。
轉載于:https://www.cnblogs.com/Just-do-it110/archive/2011/07/30/2121946.html
總結
以上是生活随笔為你收集整理的Unix环境高级编程学习笔记(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL中常用的日期计算
- 下一篇: [翻译]No.9352 SharePoi