APUE學習筆記 第三章 文件I/O

APUE學習筆記 第三章 文件I/O

1、函數open和openat

       調用open或openat函數可以打開或創建一個文件

#include<fcntl.h>
Int 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_APPEND 當讀寫文件時會從文件尾開始移動, 也就是所寫入的數據會以附加的方式加入到文件後面.
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_WRONLY | O_APPEND);          // 追加的方式打開
open('test', O_RDWR);                       // 讀寫的方式打開
open('test', O_WRONLY | O_CREAT, 0666);     // 創建文件,只寫,權限是 0666
open('test', O_WRONLY | O_TRUNC);      // 只寫打開,同時把文件長度截斷成 0.

 

2、函數creat

       調用creat函數創建一個新文件

#include<fcntl.h>
Int creat(const char* path,mode_t mode);
返回值:若成功,返回爲只寫打開的文件描述符;若出錯,返回-1.

       此函數等效於open(path,O_WRONLY | O_CREAT |O_TRUNC,mode);

creat函數的不足之處是它以只寫方式打開所創建的文件。

示例:

creat("foo",0666);

 

3、函數close

       可調用close函數關閉一個打開的文件

#include<unistd.h>
Int close(int fd);
返回值:若成功,返回0;若失敗,返回-1;

       關閉一個文件時還會釋放該進程加在該文件上的所有記錄鎖。

 

4、函數lseek

可調用lseek顯式地爲一個打開文件設置偏移量。

#include<unistd.h>
off_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函數從打開的文件中讀數據。

#include<unistd.h>
ssize_t read(int fd,void *buf,size_t nbytes);
//返回值:若成功,返回讀到的字節數,若已到達文件尾,返回0;若出錯,返回-1.
//示例:read(srcfd, buffer, BUFFERSIZE);

6、函數write

       調用write函數向打開文件寫數據。

#include<unistd.h>
ssize_t write(int fd,const void* buf,size_t nbytes);
//返回值:若成功,返回已寫的字節數;若出錯,返回-1.

       其返回值通常與參數nbytes的值相同,否則表示出錯,出錯的一個常見原因是磁盤已寫滿,或者超過了一個給定進程的文件長度限制。

示例:write(dstfd, buffer, len);

 

7、原子操作

        原子操作指的是不可再分的指令操作,即在執行原子操作時不可能被打斷,要麼原子操作沒有執行,要麼已經執行完畢。

       原子操作的實現必須需要硬件的支持,操作系統僅僅是在硬件指令的基礎之上進行一次封裝。對於沒有實現原子操作的硬件,則需要操作系統從軟件算法層面進行支持。

 

8、函數pread和pwrite

#include<unistd.h>
ssize_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

       下面兩個函數都可以用來複制一個現有的文件描述符。

#include<unistd.h>
int dup(int fd);
int dup2(int fd,int fd2);	//用fd2指定新的文件描述符
  //兩函數的返回值:若成功,返回新的文件描述符;若出錯,返回-1.

       這些函數返回的新文件描述符與參數fd共享同一個文件表項。

示例:

 newfd = dup(fd); 


10、函數sync、fsync和fdatesync

       通常,當內核需要重用緩衝區來存放其他數據塊數據時,它會把所有延遲寫數據塊寫入磁盤。

#include<unistd.h>
Int fsync(int fd);
Int fdatesync(int fd);
返回值:若成功,返回0;若出錯,返回-1;
void sync(void);

       sync只將所有修改過的快緩衝區排入寫隊列,然後就返回,不等待實際寫磁盤操作結束;

       fsync函數只對文件描述符fd指定的一個文件起作用,並等待寫磁盤操作結束才返回;

       fdatesync函數類似於fsync,但它隻影響文件的數據部分,除數據外,fsync還會同時更新文件的屬性。

 

11、函數fcntl

       函數fcntl可以改變已經打開文件的屬性。

#include<unistd.h>  
#include<fcntl.h>  
int 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)。

https://blog.csdn.net/pbymw8iwm/article/details/7974789

 

發佈了33 篇原創文章 · 獲贊 8 · 訪問量 8189
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章