一、低階檔案i/o
1、系統呼叫:
open( ),read( ),write( ),lseek( ),close( ),fcntl( ), ioctl( )
2、檔案描述
當開啟乙個現存盤案或建立乙個新檔案時,核心向程序返回乙個檔案描述符。當讀、寫乙個檔案時,用open或creat返回的檔案描述符標識該檔案,將其作為引數傳送給read、write、lseek和close等。
按照慣例,unix shell使檔案描述符:
0-stdin 1-stdout 2-stderr
在posix.1應用程式中,標準i/o描述符被定義為:
0-stdin_fileno; 1-stdout_fileno; 2-stderr_ fileno
這些常數都定義在標頭檔案中。
檔案描述符的範圍是0 ~ open_max。早期的unix版本採用的上限值是1 9 (即2 0),現在很多系統則將其增加至6 3且可以以核心引數的辦法設定,比方說1024。
3、原始系統資料型別
在unix/linux的開發過程中用到的以_t結尾的資料為系統原始資料。
系統原始資料在標頭檔案中被定義。包含此標頭檔案。
4、出錯處理
unix函式出錯時,往常返回乙個負值,而且整型變數errno通常設定為具有特定資訊的乙個值。例如,open函式如成功執行則返回乙個非負檔案描述符,如出錯則返回-1。
在open出錯時,有大約1 5種不同的errno值。某些函式並不返回負值而是使用另一種約定。例如,返回乙個指向物件的指標的大多數函式,在出錯時,將返回乙個null指標。
檔案中定義了變數errno以及可以賦與它的各種常數。這些常數都以e開頭。
在linux系統中,errno定義在標頭檔案/usr/include/asm/errno.h,多達124條。
1)errno
posix定義errno為:extern int errno;
對於errno應當知道兩條規則:
(1) 如果沒有出錯,則其值不會被乙個例程清除。因此,僅當函式的返回值指明出錯時,才檢驗其值。
(2) 任一函式都不會將errno值設定為0,在中定義的所有常數都不為0。
2)錯誤處理的標準函式
(1)strerror( ):
功能:以字串方式列印錯誤資訊。
用法:#include
char *strerror(int errnum) ;
返回:指向訊息字串的指標。
(2)perror()
功能:在標準錯誤上產生一條基於errno的當前值出錯訊息。
用法:#include
void perror(const char * msg) ;
輸入:首先輸出由msg指向的字串,然後是乙個冒號,乙個空格,然後是對應於errno值的出錯資訊,然後是乙個新行符。
(3)處理錯誤的例子
#include main(int argc, char *argv[ ])
輸出:假設,編譯後生成a.out,則輸出為:
eacces: permission denied
./a.out: no such file or directory
二、系統呼叫
(1) open
open可以開啟或建立乙個檔案,並返回乙個檔案描述符。
呼叫方法:
#include
#include
#include
int open(const char * pathname, int oflag) ;
int open(const char * pathname, int oflag, mode_t mode ) ;
返回值:成功時為檔案描述符,出錯則為-1。
open的引數
pathname是要開啟或建立的檔案的名字。
oflag引數可用來說明此函式的多個選擇項。用下列乙個或多個常數進行或運算構成oflag引數(在fcntl.h中):
• o_rdonly:唯讀開啟。 • o_wronly:只寫開啟。
• o_creat 若不存在則建立它。需同時使用第三個引數mode。
• o_excl 如果同時指定了o_creat,而檔案已經存在,則出錯。這可測試乙個檔案是否存在,如果不存在則建立此檔案成為乙個原子操作。
• o_trunc 如果此檔案存在,則將其長度截短為0。
• o_noctty 如果pathname指的是終端裝置,則不將此裝置分配作為此程序的控制終端。
• o_nonblock 如果pathname指的是特殊檔案,此選擇項為此檔案的本次開啟操作和後續的i / o操作設定非阻塞方式。
(2) creat
功能:建立乙個新檔案
用法:#include
#include
#include
int creat(const char * pathname, mode_t mode) ;
返回:成功為只寫開啟的檔案描述符;出錯為-1。
注意:此函式等效於:
open (pathname, o_wronly|o_creat|o_trunc, mode);
(3) read
功能:從描述符為filedes的檔案讀資訊。
用法:#include
ssize_t read(int filedes, void *buff, size_t nbytes);
返回:讀到的位元組數,若已到檔案尾為0,若出錯為-1。
在unix/linux 可重定義為:
int read(int fd, char *buff, unsigned nbytes);
(4) write
功能:向已開啟的檔案寫資料。
用法:#include
ssize_t write(int filedes, const void * buff, size_t nbytes) ;
返回值:若成功為已寫入的位元組數;出錯為-1。
int write(int fd, char *buff, unsigned nbytes);
(5) 檔案位置指標
檔案位置指標可以通過系統呼叫lseek來移動。
(6) lseek
功能:顯式地定位乙個開啟檔案的位置指標。
用法:#include
#include
off_t lseek(int filedes, off_t offset, int whence) ;
返回值:若成功為新的檔案位移,若出錯為-1。
說明:對引數offset 的解釋與引數whence的值有關:
whence=seek_set(0),從檔案開始。
whence=seek_cur(1),從當前位置, offset可正可負。
whence=seek_end(2),從檔案末尾, offset可為正或負。
例:求檔案的當前位置指標:
off_t currpos; currpos = lseek(fd, 0, seek_cur);
這種方法也可用來確定所涉及的檔案是否可以設定位移量。如果檔案描述符引用的是乙個管道或fifo,則lseek返回-1,並將errno設定為epipe。
(7) fcntl
功能:控制和改變已經開啟檔案的屬性。
用法:#include
#include
#include
int fcntl(int filedes, int cmd, long arg );
int fcntl(int filedes, int cmd, struct flock *lock );
返回值:若成功則依賴於cmd(見下),若出錯為-1
fcntl函式有五種功能
• 複製乙個現存的描述符(cmd=f_dupfd),新檔案描述符作為函式值返回。它是尚未開啟的各描述符中大於或等於第三個引數值中各值的最小值。新描述符與filedes 共享同一檔案表項;
• 獲得/設定檔案描述符標記(cmd=f_getfd/f_setfd);對應於filedes的檔案描述符標誌作為函式值返回。
• 獲得/設定非同步i/o有權(cmd=f_getown/f_setown);獲取或接收當前接收sigio和sigurg訊號的程序id或程序組id。
• 獲得/設定記錄鎖(cmd=f_getlk, f_setlk或f_setlkw)。
(8) ioctl函式
ioctl 函式是i/o操作的雜物箱。不能用本章中其他函式表示的i/o操作通常都能用ioctl表示。
終端i/o是ioctl的最大使用方面(第11章將介紹posix.1已經用新的函式代替ioctl進行終端i/o操作)。
ioctl更多的是用於裝置控制,比如磁碟的格式化,modem裝置,磁帶的快進、快倒等。
例子
#include #include #include main( )
if(write(fd,myc,strlen(myc))!=strlen(myc))
close(fd);
}
unix系統之與檔案系統相關的系統呼叫
自unix誕生之初,檔案系統便成為了unix系統的一部分。儘管那時的檔案系統只能支援512k位元組的磁碟且每個檔案限定長度為64k位元組。但是檔案系統的基礎結構已經基本確定。構建在檔案系統之上的相關的系統呼叫也已基本成型。後來發展的與檔案系統相關的系統呼叫也是在其基礎之上不斷完善而來的。unix中與...
系統呼叫相關理解
系統呼叫是核心提供的使用者程序與核心進行互動的一組介面 是應用程式受限地訪問介面 提供了建立新程序並與已有程序進行通訊的機制 提供了申請作業系統其它資源的能力 是使用者訪問核心的唯一手段。主要是為了保證系統穩定可靠,避免應用程式肆意妄為。系統呼叫作為使用者空間程序和硬體裝置之間的中間層,主要作用有以...
Linux 檔案相關系統呼叫介面(IO)
早期在寫c語言介面的時候,我們可以通過fopen來開啟乙個檔案,下面這段兩段 為例 hello.c寫檔案 1 include 2 include 3 int main 4 9 const char msg hello world n 10 int count 5 11 while count 14 ...