1、概述:
(1)、unix類作業系統最重要的兩個東東:進程和檔案
(2)、大多數檔案I/O用到的5個函數:open, close, read, write, lseek. 還有檔案屬性操作函數:dup, fcntl
(3)、unix類作業系統的檔案I/O是不帶緩衝的I/O(unbuffered-I/O)
2、檔案描述符(file descriptor ,縮寫fd)
(1)、unix類系統一般用0,1,2分別表示STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO,來聯絡進程的標準輸入,標準輸出,和標準錯誤。
(2)、範圍是0到OPEN_MAX
3、oepn: int open(const char *passname, int oflag, .../* , mode_t mode */);
(1)、oflag的值如下:
a、O_RDONLY, O_WRONLY, O_RDWR注意的是這三個東西不是各佔一個二進位位,二是0, 1, 2,所以判斷是唯讀,唯寫,讀寫時不能用 flag & O_RDONLY的方法,只能用flag == O_RDONLY。
b、O_CREAT、O_EXCL 兩個一起用時,提供一個原子操作,當檔案已存在時返回錯誤,否則建立檔案;如果沒有O_EXCL,則當檔案存在時,忽略。用O_CREAT時候,需要有檔案的mode_t參數。
c、O_NONBLOCK:此標誌只適用於fifo,塊裝置檔案和字元裝置檔案。
d、O_TRUNC:如果檔案以唯讀或唯寫方式開啟,則該檔案長度截取為0;
e、O_SYNC:每一次write都等到物理操作完成後再返回。
4、close:int close(int fd);
注意:進程結束時候,核心會自動關閉該進程開啟的所有檔案,有很多程式利用了這一點。
5、lseek:off_t lseek(int fd, off_t offset, int whence);
參數whence的取值:SEEK_SET, SEEK_CUR, SEEK_END分標識檔案的開頭,當前指標,和結尾。
如果是SEEK_SET,則將當前位移量設定到檔案開始處offset位元組;如果是SEEK_CUR,則offset是相對於檔案指標的當前位置;如果是SEEK_END,則offset相對於檔案的末尾。後兩種請況的offset可正可負。
返回新的檔案位移量,注意某些 體統某種情況需要返回負值,因此這個測試應該是判斷傳回值是否為-1,而不是判<0
6、read: ssize_t read(int fd, void *buf, size_t len);
write: ssize_t write(int fd, void *buf, size_t len);
注意read傳回值:如成功,返回實際讀入buf的位元組數;如到達檔案尾部,返回0;出錯,返回-1
7、檔案分享權限設定,在UNIX類作業系統中,檔案可以供幾個進程同一時間段訪問。
每一個進程有一個進程記錄項,而每個進程項當中有一子項是檔案描述符數組。如下:
struct 進程記錄項
{
...
struct 檔案表[] //[]表示這是一個數組。
...
};
struct 檔案表
{
檔案當前的狀態; //比如是唯讀,唯寫,讀寫,阻塞等等
檔案當前的位移指標;
struct 檔案資訊 *; //也就是指向檔案資訊的指標
};
struct 檔案資訊
{
檔案許可權;
檔案大小;
檔案i節點;
...
};
每個進程有自己的開啟的檔案表數組和檔案表結構,而開啟的檔案的檔案資訊是整個核心共同維護一份的。
8、原子操作舉例:
比如:如果設定了O_APPEND標誌,則進程在每次寫檔案之前,都把當前位移移到檔案的末尾。
比如:O_CREAT | O_EXCL 標記和沒有該標記時實現的功能相比。
9、dup函數:int dup(int fd);
在進程裡拷貝一份進程描述符。但是檔案表公用的。
10、fcntl:改變檔案屬性的函數。int fcntl(int fd, int cmd, .../* int arg */);
這個函數5個方面的用途:
a、複製檔案描述符(cmd = F_DUPFD) 相當於 dup(fd);
b、檔案描述符標誌 (cmd = F_GETFD 或 cmd = F_SETFD)
c、檔案狀態標誌(cmd = F_GETFL 或 cmd = F_SETFL)
:F_SETFL可以設定的幾個標誌是:O_APPEND, O_SYNC, O_NONBLOCK,O_ASYNC
d、非同步I/O許可權(cmd = F_GETOWN 或 cmd = F_SETOWN)
e、記錄鎖(cmd = F_GETTLK 或 cmd = F_SETTLK 或 cmd = F_SETLKW):進階I/O部分
11、/dev/fd目錄:開啟檔案/dev/fd/n相當於複製描述符n