apue學習筆記(第三章 檔案I O)

2021-07-04 13:00:27 字數 4369 閱讀 7463

本章開始討論unix系統,先說明可用的檔案i/o函式---開啟檔案、讀寫檔案等

unix系統中的大多數檔案i/o只需用到5個函式:open、read、write、lseek以及close

open函式  返回乙個最小的未用描述符

#include int open(const char *pathname, int flags);

int open(const char *pathname, int flags, mode_t mode);

其中path引數是開啟或建立檔案的名字,flags引數由下列乙個或多個常量進行「或」運算得到:

o_rdonly  唯讀開啟

o_wronly  只寫開啟

o_rdwr     讀、寫開啟

o_exec  只執行開啟

o_search  只搜尋開啟(應用於目錄)

這5個常量中必須指定乙個,下列常量則是可選的:

o_cloexec  把fd_cloexec常量設定為檔案描述符標誌

o_creat  若此檔案不存在則建立它。使用此選項時,open函式必須同時說明第三個引數mode

o_directory  如果path引用的不是目錄,則出錯

o_exel  如果同時指定了o_creat,而檔案已經存在,則出錯

o_noctty  如果path引用的是終端裝置,則不講該裝置分配作為此程序的控制終端

o_nofollow  如果path應用的是乙個符號鏈結,則出錯

o_nonblock  如果path引用的是乙個fifo、乙個塊特殊檔案或乙個字元特殊檔案,則設定此檔案本次開啟操作跟後續的i/o操作為非阻塞方式

o_sync  使每次write等待物理i/o操作完成

o_trunc  如果此檔案存在,而且為只寫或讀寫成功開啟,則將其長度截斷為0

o_tty_init  如果開啟乙個還未開啟的終端裝置,設定非標準termios引數值

creat函式

#include int creat(const char *path,mode_t mode);
該函式相當於open(path,o_wronly|o_create|o_trunc,mode);

在第四章我們會詳細說明檔案訪問許可權,並說明如何指定mode

close函式

#include int close(int fd);
close函式用於關閉乙個開啟檔案

lseek函式

#include off_t lseek(int fd,off_t offset,int whence);
對引數offset的解釋與引數whence的值有關。

若whence是seek_set,則將該檔案的偏移量設定為距距檔案開始處offset個位元組

若whence是seek_cur,則將該檔案的偏移量設定為其當前值加offset,offset可為正或負

若whence是seek_end,則將該檔案的偏移量設定為檔案長度加offset,offset可正可負

若lseek成功執行,則返回新的檔案偏移量,為此可以用下列方式確定開啟檔案的當前偏移量

off_t currpos;

currpos=lseek(fd,0,seek_cur);

如果檔案描述符指向的是乙個管道、fifo、或者網路套接字,則lseek返回-1,並將errno設定為espipe。

read函式

#include ssize_t read(int fd,void *buf,size_t nbytes);
如read成功,則返回讀到的位元組數。如已到達檔案的尾端,則返回0。

讀操作從檔案的當前偏移量處開始,在成功返回之前,該偏移量將增加實際讀到的位元組數。

write函式

#include ssize_t write(int fd,const void *buf,size_t nbytes);
其返回值通常與引數nbytes的值相同,否則表示出錯。write出錯的乙個常見的原因是磁碟已寫滿,或者超過了乙個給定程序的檔案長度限制。

在一次成功寫之後,該檔案偏移量增加實際寫得位元組數。

函式dup和dup2

#include int dup(int fd);

int dup2(int fd,int fd2);

兩個函式都可用來複製乙個現有的檔案描述符

dup返回的新檔案描述符一定是當前可用檔案描述符中的最小數值。

dup2可以用fd2引數指定新描述符的值。如果fd2已經開啟,則先將其關閉。若fd等於fd2,則返回fd2,而不關閉它。

這些函式返回的新檔案描述符與引數fd共享乙個檔案表項,如下圖所示:

digit1>&digit2表示要將描述符digit1重定向至描述符digit2的同一檔案

理解./a.out > outfile 2>&1與./a.out 2>&1 >outfile的區別

fcnt函式

#include int fcntl(int fd,int cmd,.../* int arg */);
fcntl函式可以改變已經開啟檔案的屬性,它有以下5種功能

1 複製乙個已有的描述符(cmd=f_dupfd或f_dupfd_cloexec)

2 獲取/設定檔案描述符標誌(cmd=f_getfd或f_setfd)

3 獲取/設定檔案狀態標誌(cmd=f_getfl或f_setfl)

4 獲取/設定非同步i/o所有權(cmd=f_getown或f_setown)

5 獲取/設定記錄鎖(cmd=f_getlk、f_setlk或f_setlkw)

我們先說明cmd中的前面8種

f_dupfd  複製檔案描述符fd,返回新的檔案描述符。它是尚未開啟的各描述符中大於或等於第三個引數值中各值的最小值

f_dupfd_cloexec  複製檔案描述符,設定與新描述符關聯的fd_cloexec檔案描述符標誌的值,返回新的檔案描述符

f_getfd  對應於fd的檔案描述符標誌做為函式值返回,當前只定義了乙個檔案描述符標誌fd_cloexec

f_setfd  對於fd設定檔案描述符標誌。

f_getfl  對應於fd的檔案狀態標誌作為函式值返回,下圖列出fcntl的檔案狀態標誌

其中,3種訪問方式標誌(o_rdonly,o_wronly,o_rdwr)並不各佔一位,因此首先必須用遮蔽字o_accmode取得訪問方式位,然後將結果與這3個值得每乙個比較。

f_gettown  獲取當前接收sigio和sigurg訊號的程序id或程序組id。

f_setown  設定接收sigio和sigurg訊號的程序id或程序組id

下面程式將列印檔案狀態標誌說明

#include "apue.h"

#include int

main(int argc, char *argv)

if (val & o_nonblock)

printf(", nonblocking");

if (val & o_sync)

printf(", synchronous writes");

#if !defined(_posix_c_source) && defined(o_fsync) && (o_fsync != o_sync)

if (val & o_fsync)

printf(", synchronous writes");

#endif

putchar('\n');

exit(0);

}

下面函式用於設定檔案狀態標誌

#include "apue.h"

#include void

set_fl(int fd, int flags) /* flags are file status flags to turn on */

APUE學習筆記 第三章 檔案I O

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,...

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...