apue學習筆記 第三章 檔案i/o
1、函式open和openat
呼叫open或openat函式可以開啟或建立乙個檔案
#includeint open(const char *path,into flag,…/*mode_t made*/);
int openat(int fd,const char* path,into flag,…/*mode_t mode*/);
兩個函式返回值:若成功,返回檔案描述符(一定是最小的未用描述符數值);若出錯,返回-1;
path引數是要開啟或建立檔案的名字;oflag引數可用來說明此函式的多個選項,用下列乙個或多個常量進行「或」運算構成oflag引數
o_rdonly 以唯讀方式開啟檔案
o_wronly 以只寫方式開啟檔案
o_rdwr 以可讀寫方式開啟檔案.
上述三種旗標是互斥的, 也就是不可同時使用, 但可與下列的旗標利用or(|)運算子組合.大多數實現將o_rdonly定義為0,o_wronly定義為1,o_rdwr定義為2;
o_exec 只執行開啟
o_search 只搜尋開啟
o_creat 若欲開啟的檔案不存在則自動建立該檔案.
o_excl 如果o_creat 也被設定, 此指令會去檢查檔案是否存在. 檔案若不存在則建立該檔案, 否則將導致開啟檔案錯誤.
此外, 若o_creat 與o_excl 同時設定, 並且欲開啟的檔案為符號連線, 則會開啟檔案失敗.
o_noctty 如果欲開啟的檔案為終端機裝置時, 則不會將該終端機當成程序控制終端機.
o_trunc 若檔案存在並且以可寫的方式開啟時, 此旗標會令檔案長度清為0, 而原來存於該檔案的資料也會消失.
o_nonblock 以不可阻斷的方式開啟檔案, 也就是無論有無資料讀取或等待, 都會立即返回程序之中.
o_ndelay 同o_nonblock.
o_sync 以同步的方式開啟檔案.
o_nofollow 如果引數pathname 所指的檔案為一符號連線, 則會令開啟檔案失敗.
o_directory 如果引數pathname 所指的檔案並非為一目錄, 則會令開啟檔案失敗。
fd引數把open和openat函式區分開來,共有三種可能性:
a、path引數指定的是絕對路徑名,此情況下,fd引數被忽略,openat函式就相當於open函式;
b、path引數指定的是相對路徑名,fd引數指定了相對路徑名在檔案系統中的開始位址;
c、 path引數指定了相對路徑名,fd引數具有特殊值at_fdcwd。在此情況下,路徑名在當前工作目錄中獲取,openat函式在操作上與open函式類似。
示例:
open('test', o_rdonly); // 唯讀方式開啟
open('test', o_rdwr); // 讀寫的方式開啟
open('test', o_wronly | o_creat, 0666); // 建立檔案,只寫,許可權是 0666
open('test', o_wronly | o_trunc); // 只寫開啟,同時把檔案長度截斷成 0.
2、函式creat
呼叫creat函式建立乙個新檔案
#includeint creat(const char* path,mode_t mode);
返回值:若成功,返回為只寫開啟的檔案描述符;若出錯,返回-1.
此函式等效於open(path,o_wronly | o_creat |o_trunc,mode);
creat函式的不足之處是它以只寫方式開啟所建立的檔案。
示例:creat("foo",0666);
3、函式close
可呼叫close函式關閉乙個開啟的檔案
#includeint close(int fd);
返回值:若成功,返回0;若失敗,返回-1;
關閉乙個檔案時還會釋放該程序加在該檔案上的所有記錄鎖。
4、函式lseek
可呼叫lseek顯式地為乙個開啟檔案設定偏移量。
#includeoff_t lseek(int fd,off_t offset,int whence);
//返回值:若成功,返回新的檔案偏移量;若出錯,返回為-1;
對引數offest的解釋與引數whence的指有關
a、若whence是seek_set,則將該檔案的偏移量設定為距檔案開始處offset個位元組;
b、若whence是seek_cur,則將該檔案的偏移量設定為當前值加offset,offset可正可負;
c、 若whence是seek_end,則將該檔案的偏移量設定為檔案長度加offset,offset可正可負。(可能產生空洞)
如果檔案描述符指向的是乙個管道、fifo或網路套接字,則lseek返回-,並將errno設定為espipe。
示例:lseek(fd, 6, seek_set);
lseek(fd,0,seek_end);
5、函式read
呼叫read函式從開啟的檔案中讀資料。
#includessize_t read(int fd,void *buf,size_t nbytes);
//返回值:若成功,返回讀到的位元組數,若已到達檔案尾,返回0;若出錯,返回-1.
//示例:read(srcfd, buffer, buffersize);
6、函式write
呼叫write函式向開啟檔案寫資料。
#includessize_t write(int fd,const void* buf,size_t nbytes);
//返回值:若成功,返回已寫的位元組數;若出錯,返回-1.
其返回值通常與引數nbytes的值相同,否則表示出錯,出錯的乙個常見原因是磁碟已寫滿,或者超過了乙個給定程序的檔案長度限制。
示例:write(dstfd, buffer, len);
7、原子操作
原子操作指的是不可再分的指令操作,即在執行原子操作時不可能被打斷,要麼原子操作沒有執行,要麼已經執行完畢。
原子操作的實現必須需要硬體的支援,作業系統僅僅是在硬體指令的基礎之上進行一次封裝。對於沒有實現原子操作的硬體,則需要作業系統從軟體演算法層面進行支援。
8、函式pread和pwrite
#includessize_t pread(int fd,void *buf,size_t nbytes,off_t offset);
//返回值:讀到的位元組數,若已到檔案尾,返回0;若出錯,返回-1;
ssize_t pwrite(int fd,const void* buf,size_t nbytes,off_t offset);
//返回值:若成功,返回已寫的位元組數,若出錯,返回-1;
呼叫pread相當於呼叫lseek後呼叫read;呼叫pwrite相當於呼叫lseek後呼叫write。
9、函式dup和dup2
下面兩個函式都可以用來複製乙個現有的檔案描述符。
#includeint dup(int fd);
int dup2(int fd,int fd2); //用fd2指定新的檔案描述符
//兩函式的返回值:若成功,返回新的檔案描述符;若出錯,返回-1.
這些函式返回的新檔案描述符與引數fd共享同乙個檔案表項。
示例:newfd = dup(fd);
10、函式sync、fsync和fdatesync
通常,當核心需要重用緩衝區來存放其他資料塊資料時,它會把所有延遲寫資料塊寫入磁碟。
#includeint fsync(int fd);
int fdatesync(int fd);
返回值:若成功,返回0;若出錯,返回-1;
void sync(void);
sync只將所有修改過的快緩衝區排入寫佇列,然後就返回,不等待實際寫磁碟操作結束;
fsync函式只對檔案描述符fd指定的乙個檔案起作用,並等待寫磁碟操作結束才返回;
fdatesync函式類似於fsync,但它只影響檔案的資料部分,除資料外,fsync還會同時更新檔案的屬性。
11、函式fcntl
函式fcntl可以改變已經開啟檔案的屬性。
#include#includeint fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd ,struct flock* lock);
返回值:若成功,則依賴於cmd;若出錯,返回-1.
fantl函式有以下5種功能:
a、複製乙個已有的描述符(cmd=f_dupfd或f_dupfd_cloexec);
b、獲取/設定檔案描述符標誌(cmd=f_getfd或f_setfd);
c、 獲取/設定檔案狀態標識(cmd=f_getfl或f_setfl);
d、獲取/設定非同步i/o所有權(cmd=f_getown或f_setown);
e、獲取/設定記錄鎖(cmd=f_getlk、f_setlk或f_setlkw)。
apue學習筆記(第三章 檔案I O)
本章開始討論unix系統,先說明可用的檔案i o函式 開啟檔案 讀寫檔案等 unix系統中的大多數檔案i o只需用到5個函式 open read write lseek以及close open函式 返回乙個最小的未用描述符 include int open const char pathname,i...
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...
《APUE》第三章筆記(1)
以下內容是我看 apue 第二版第三章的筆記,有錯還希望指出來,謝謝。unbuffered i o,跟buffered i o相對,buffered i o就是 iso c標準下的標準輸入輸出函式,而unbuffered i o就是posix下的函式。檔案描述符,個人理解就相當於linux下的uid...