APUE學習筆記-記錄二,apue學習筆記記錄
這次回顧APUE中第三四章的內容,主要是檔案I/O操作相關的介面函數。
UNIX系統的檔案I/O是不帶緩衝的I/O,不帶緩衝是指每個read和write都調用系統核心的一個系統調用。
1.檔案描述符
UNIX I/O的所有函數都是基於檔案描述符來操作的。那什麼是檔案描述符呢?檔案描述符是一個非負整數。當開啟一個現有檔案或建立一個新檔案時,核心向進程返回一個檔案描述符。該檔案描述符fd是所有UNIX I/O函數的操作對象。UNIX系統把檔案描述符0與進程標準輸入關聯,把檔案描述符1與進程標準輸出關聯,把檔案描述符2與標準錯誤關聯。我們一般在程式中用STDINPUT_FILENO,STDOUTPUT_FILENO,STDERR_FILENO代替這幾個檔案描述符。檔案描述符的範圍是0~OPEN_MAX-1。
2.基本I/O函數
#include <fcntl.h>
int open(const char *path,int oflag,.../* mode_t mode */); /* xx */
int openat(int fd,const char *path,int oflag,.../* mode_t mode */);
【成功返迴文件描述符,出錯返回-1】
調用open函數開啟一個檔案,path是要開啟或建立的檔案的名字,oflag用來說明該函數的多個選項。對於openat函數,在UNIX這一系列I/O函數中有很多類似openat帶at尾碼的xxat函數,它們的功能與xx函數類似,只不過是xx函數是用檔案的絕對路徑名來調用,而xxat函數是用檔案描述符加上相對路徑名來調用,對xxat類函數來說,當path參數指向一個絕對路徑名時,其參數fd也失效,此時xxat函數與xx函數相同。(再後面對於這種函數我會用xx注釋說明,就不再列出xxat函數了)。
open函數的oflag參數是用多個系統定義的常量做‘或’運算得出。首先是O_RDONLY,O_WRONLY,O_RDWR,O_EXEC,O_SEARCH(這五個常量中必須指定一個且只能指定一個)。剩下的我只列出幾個我覺得用的頻繁些的:O_APPEND,每次寫時都追加到檔案末尾;O_CREAT,若此檔案不存在則建立,使用該選項時,函數第三個參數mode需指定檔案存取權限;O_TRUNC,若檔案存在,且是唯寫或讀-寫開啟,則將檔案長度截斷為零。
#include <fcntl.h>
int creat(const char *path,mode_t mode);
【成功,返回以WRONLY開啟的檔案描述符;出錯返回-1】
#include <unistd.h>
int close(int fd);【成功,返回0;出錯返回-1】
註:當一個進程終止時,核心會自動關閉它開啟的所有檔案,因此很多程式都利用這一點不顯式調用close關閉。
off_t lseek(int fd,off_t offset,int whence);【成功,返迴文件新的位移量;失敗返回-1】
whence有三種值:SEEK_SET,此時檔案位移量設定為據檔案開始初offset個位元組處;SEEK_CUR,此時將檔案位移量設定為其當前值加offset;SEEK_END,此時檔案位移量設定為檔案長度加offset。
ssize_t read(int fd,void *buf,size_t nbytes);【成功,返回讀到位元組數,若已到檔案尾,返回零;出錯返回-1】
從檔案描述符所指檔案讀n位元組到buf數組。ssize_t是帶符號傳回值int,size_t是unsigned int
ssize_t write(int fd,void *buf,size_t nbytes);【成功,返回已寫位元組數;出錯返回-1】
從buf數組讀n位元組寫入fd所指檔案。對普通檔案,寫操作從檔案當前位移量出開始;對於檔案開啟時指定了O_APPEND位,每次寫操作是在檔案末尾。
3.檔案分享權限設定
UNIX支援在不同進程間共用開啟檔案。UNIX核心表示開啟檔案的資料結構如下所示(手機拍的湊合著看):
a.每個進程在進程表中都有一個記錄項,記錄項包含一張開啟檔案的檔案描述符表,表中每一項關聯檔案描述符標誌及一個指向檔案表項的指標。
b.核心為所有開啟檔案維持一張檔案表,每個表項包含檔案狀態標誌,當前檔案位移量,v節點指標。
c.每個開啟檔案都有一個v節點結構。v節點包含了檔案類型和對檔案進行各種操作的函數指標。還包含了檔案的i節點,i節點包含了檔案的所有者,檔案長度,指向檔案實際資料區塊在磁碟上的指標等資訊。
兩獨立進程各自開啟同一檔案的:
#include <unistd.h>
int dup(int fd);【成功,返回新檔案描述符,出錯返回-1】
複製現有檔案描述符,返回的檔案描述符是當前可用的檔案描述符中最小的那個。
int fsync(int fd);
int fdatasync(int fd);
【成功,返回0,出錯返回-1】
void sync(void);
sync只是將所修改的塊緩衝區加入寫隊列,然後就返回,不等待寫磁碟操作解數。
fsync只對檔案描述符fd指定的檔案有用,且要等寫磁碟操作完成才返回。
fdatasync類似於fsync,只是fdatasync隻影響檔案資料部分。
#include <fcntl.h>
int fcntl(int fd,int cmd,.../* arg */);
該函數用於改變已開啟檔案的屬性。fcntl的功能與cmd有關。
就這樣。。。