1. fopen
打開普通文件
帶緩沖區
緩沖文件系統是借助文件結構體指針來對文件進行管理,通過文件指針來對文件進行訪問,既可以讀寫字符、字符串、格式化數據,也可以讀寫二進制數據。
函數原型:FILE *fopen (const char * path,const char * mode);
所需庫:<stdio.h>
返回值:文件順利打開后,指向該流的文件指針就會被返回。如果文件打開失敗則返回NULL,並把錯誤代碼存在errno 中。
參數說明:
參數path字符串包含欲打開的文件路徑及文件名,參數mode字符串則代表着流形態。
mode有下列幾種形態字符串:
r 以只讀方式打開文件,該文件必須存在。
r+ 以可讀寫方式打開文件,該文件必須存在。
rb+ 讀寫打開一個二進制文件,允許讀寫數據。
rw+ 讀寫打開一個文本文件,允許讀和寫。
w 打開只寫文件,若文件存在則文件長度清為0,即該文件內容會消失。若文件不存在則建立該文件。
w+ 打開可讀寫文件,若文件存在則文件長度清為零,即該文件內容會消失。若文件不存在則建立該文件。
a 以附加的方式打開只寫文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數據會被加到文件尾,即文件原先的內容會被保留。(EOF符保留)
a+ 以附加方式打開可讀寫的文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數據會被加到文件尾后,即文件原先的內容會被保留。 (原來的EOF符不保留)
wb 只寫打開或新建一個二進制文件;只允許寫數據。
wb+ 讀寫打開或建立一個二進制文件,允許讀和寫。
ab+ 讀寫打開一個二進制文件,允許讀或在文件末追加數據。
at+ 打開一個叫string的文件,a表示append,就是說寫入處理的時候是接着原來文件已有內容寫入,不是從頭寫入覆蓋掉,t表示打開文件的類型是文本文件,+號表示對文件既可以讀也可以寫。
上述的形態字符串都可以再加一個b字符,如rb、w+b或ab+等組合,加入b 字符用來告訴函數庫以二進制模式打開文件。如果不加b,表示默認加了t,即rt,wt,其中t表示以文本模式打開文件。由fopen()所建立的新文件會具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)權限,此文件權限也會參考umask 值。
有些C編譯系統可能不完全提供所有這些功能,有的C版本不用"r+","w+","a+",而用"rw","wr","ar"等,讀者注意所用系統的規定。
例:FILE* dstfile;
FILE* ret;
ret=fopen("dstfile","w+");
fopen與fclose是一一對應的。
2. open
打開設備文件
不帶緩沖區
非緩沖文件系統依賴於操作系統,通過操作系統的功能對文件進行讀寫,是系統級的輸入輸出,它不設文件結構體指針,只能讀寫二進制文件,但效率高、速度 快
函數原型:int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
所需庫:#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>
返回值:成功則返回文件描述符,否則返回 -1;
參數說明:
參數 pathname 指向欲打開的文件路徑字符串. 下列是參數flags 所能使用的旗標:
O_RDONLY 以只讀方式打開文件
O_WRONLY 以只寫方式打開文件
O_RDWR 以可讀寫方式打開文件. 上述三種旗標是互斥的, 也就是不可同時使用, 但可與下列的旗標利用OR(|)運算符組合.
O_CREAT 若欲打開的文件不存在則自動建立該文件.
O_EXCL 如果O_CREAT 也被設置, 此指令會去檢查文件是否存在. 文件若不存在則建立該文件, 否則將導致打開文件錯誤. 此外, 若O_CREAT 與O_EXCL 同時設置, 並且欲打開的文件為符號連接, 則會打開文件失敗.
O_NOCTTY 如果欲打開的文件為終端機設備時, 則不會將該終端機當成進程控制終端機.
O_TRUNC 若文件存在並且以可寫的方式打開時, 此旗標會令文件長度清為0, 而原來存於該文件的資料也會消失.
O_APPEND 當讀寫文件時會從文件尾開始移動, 也就是所寫入的數據會以附加的方式加入到文件后面.
O_NONBLOCK 以不可阻斷的方式打開文件, 也就是無論有無數據讀取或等待, 都會立即返回進程之中.
O_NDELAY 同O_NONBLOCK.
O_SYNC 以同步的方式打開文件.
O_NOFOLLOW 如果參數pathname 所指的文件為一符號連接, 則會令打開文件失敗.
O_DIRECTORY 如果參數pathname 所指的文件並非為一目錄, 則會令打開文件失敗。注:此為Linux2. 2 以后特有的旗標, 以避免一些系統安全問題.
參數mode 則有下列數種組合, 只有在建立新文件時才會生效, 此外真正建文件時的權限會受到umask 值所影響, 因此該文件權限應該為 (mode-umaks).
S_IRWXU00700 權限, 代表該文件所有者具有可讀、可寫及可執行的權限.
S_IRUSR 或S_IREAD, 00400 權限, 代表該文件所有者具有可讀取的權限.
S_IWUSR 或S_IWRITE, 00200 權限, 代表該文件所有者具有可寫入的權限.
S_IXUSR 或S_IEXEC, 00100 權限, 代表該文件所有者具有可執行的權限.
S_IRWXG 00070 權限, 代表該文件用戶組具有可讀、可寫及可執行的權限.
S_IRGRP 00040 權限, 代表該文件用戶組具有可讀的權限.
S_IWGRP 00020 權限, 代表該文件用戶組具有可寫入的權限.
S_IXGRP 00010 權限, 代表該文件用戶組具有可執行的權限.
S_IRWXO 00007 權限, 代表其他用戶具有可讀、可寫及可執行的權限.
S_IROTH 00004 權限, 代表其他用戶具有可讀的權限
S_IWOTH 00002 權限, 代表其他用戶具有可寫入的權限.
S_IXOTH 00001 權限, 代表其他用戶具有可執行的權限.
返回值:若所有欲核查的權限都通過了檢查則返回0 值, 表示成功, 只要有一個權限被禁止則返回-1.
錯誤代碼:
EEXIST 參數pathname 所指的文件已存在, 卻使用了O_CREAT 和O_EXCL 旗標.
EACCESS 參數pathname 所指的文件不符合所要求測試的權限.
EROFS 欲測試寫入權限的文件存在於只讀文件系統內.
EFAULT 參數pathname 指針超出可存取內存空間.
EINVAL 參數mode 不正確.
ENAMETOOLONG 參數 pathname 太長.
ENOTDIR 參數pathname 不是目錄.
ENOMEM 核心內存不足.
ELOOP 參數pathname 有過多符號連接問題.
EIO I/O 存取錯誤.
附加說明:使用 access()作用戶認證方面的判斷要特別小心, 例如在access()后再作open()空文件可能會造成系統安全上的問題.
O_RDONLY 以只讀方式打開文件
O_WRONLY 以只寫方式打開文件
O_RDWR 以可讀寫方式打開文件. 上述三種旗標是互斥的, 也就是不可同時使用, 但可與下列的旗標利用OR(|)運算符組合.
O_CREAT 若欲打開的文件不存在則自動建立該文件.
O_EXCL 如果O_CREAT 也被設置, 此指令會去檢查文件是否存在. 文件若不存在則建立該文件, 否則將導致打開文件錯誤. 此外, 若O_CREAT 與O_EXCL 同時設置, 並且欲打開的文件為符號連接, 則會打開文件失敗.
O_NOCTTY 如果欲打開的文件為終端機設備時, 則不會將該終端機當成進程控制終端機.
O_TRUNC 若文件存在並且以可寫的方式打開時, 此旗標會令文件長度清為0, 而原來存於該文件的資料也會消失.
O_APPEND 當讀寫文件時會從文件尾開始移動, 也就是所寫入的數據會以附加的方式加入到文件后面.
O_NONBLOCK 以不可阻斷的方式打開文件, 也就是無論有無數據讀取或等待, 都會立即返回進程之中.
O_NDELAY 同O_NONBLOCK.
O_SYNC 以同步的方式打開文件.
O_NOFOLLOW 如果參數pathname 所指的文件為一符號連接, 則會令打開文件失敗.
O_DIRECTORY 如果參數pathname 所指的文件並非為一目錄, 則會令打開文件失敗。注:此為Linux2. 2 以后特有的旗標, 以避免一些系統安全問題.
參數mode 則有下列數種組合, 只有在建立新文件時才會生效, 此外真正建文件時的權限會受到umask 值所影響, 因此該文件權限應該為 (mode-umaks).
S_IRWXU00700 權限, 代表該文件所有者具有可讀、可寫及可執行的權限.
S_IRUSR 或S_IREAD, 00400 權限, 代表該文件所有者具有可讀取的權限.
S_IWUSR 或S_IWRITE, 00200 權限, 代表該文件所有者具有可寫入的權限.
S_IXUSR 或S_IEXEC, 00100 權限, 代表該文件所有者具有可執行的權限.
S_IRWXG 00070 權限, 代表該文件用戶組具有可讀、可寫及可執行的權限.
S_IRGRP 00040 權限, 代表該文件用戶組具有可讀的權限.
S_IWGRP 00020 權限, 代表該文件用戶組具有可寫入的權限.
S_IXGRP 00010 權限, 代表該文件用戶組具有可執行的權限.
S_IRWXO 00007 權限, 代表其他用戶具有可讀、可寫及可執行的權限.
S_IROTH 00004 權限, 代表其他用戶具有可讀的權限
S_IWOTH 00002 權限, 代表其他用戶具有可寫入的權限.
S_IXOTH 00001 權限, 代表其他用戶具有可執行的權限.
返回值:若所有欲核查的權限都通過了檢查則返回0 值, 表示成功, 只要有一個權限被禁止則返回-1.
錯誤代碼:
EEXIST 參數pathname 所指的文件已存在, 卻使用了O_CREAT 和O_EXCL 旗標.
EACCESS 參數pathname 所指的文件不符合所要求測試的權限.
EROFS 欲測試寫入權限的文件存在於只讀文件系統內.
EFAULT 參數pathname 指針超出可存取內存空間.
EINVAL 參數mode 不正確.
ENAMETOOLONG 參數 pathname 太長.
ENOTDIR 參數pathname 不是目錄.
ENOMEM 核心內存不足.
ELOOP 參數pathname 有過多符號連接問題.
EIO I/O 存取錯誤.
附加說明:使用 access()作用戶認證方面的判斷要特別小心, 例如在access()后再作open()空文件可能會造成系統安全上的問題.
例:ipu_fd=open("/dev/ipu",O_RDWR);
close(ipu_fd);
open與close是一一對應的。
ipu_fd就是文件描述符,可以通過文件描述符去找到該設備或文件。
