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