不帶緩存的文件I/O操作主要有5個函數open、read、write、lseek和close。這幾個不帶緩存的操作是指每一個函數都只調用系統中的一個函數。這些函數不是ANSIC組成部分,但屬於POSIX的組成部分。
1.open函數(返回的文件描述符一定是最小的且沒有被用過的數值)
open 函數用於打開和創建文件。
所需都文件
#include<sys/types.h>//提供pid_t類型的定義
#include<sys/stat.h>
#include<fcntl.h>
函數原型 int open(const char *pathname, int flags, ... /* mode_t mode */);
返回值:成功則返回文件描述符,否則返回 -1
pathname 是待打開/創建文件的路徑名(如 C:/cpp/a.cpp);
第三個參數 (...)僅當創建新文件時才使用,用於指定文件的訪問權限位(access permission bits)。
flags 用於指定文件的打開/創建模式,這個參數可由以下常量(定義於 fcntl.h)通過邏輯或(|)構成。
O_RDONLY 只讀模式
O_WRONLY 只寫模式
O_RDWR 讀寫模式
打開/創建文件時,用且只能用三個常量中的一個。以下常量是選用的:
O_APPEND 每次寫操作都寫入文件的末尾
O_CREAT 如果指定文件不存在,則創建這個文件
O_EXCL 如果要創建的文件已存在,則返回 -1,並且修改 errno 的值,用於測試文件是否存在
O_TRUNC 如果文件存在,並且以只寫/讀寫方式打開,則清空文件全部內容
O_NOCTTY 如果路徑名指向終端設備,不要把這個設備用作控制終端。
O_NONBLOCK 如果路徑名指向 FIFO/塊文件/字符文件,則把文件的打開和後繼 I/O
設置爲非阻塞模式(nonblocking mode)
以下三個常量同樣是選用的,它們用於同步輸入輸出
O_DSYNC 等待物理 I/O 結束後再 write。在不影響讀取新寫入的數據的前提下,不等待文件屬性更新。
O_RSYNC read 等待所有寫入同一區域的寫操作完成後再進行
O_SYNC 等待物理 I/O 結束後再 write,包括更新文件屬性的 I/O
(2)訪問權限位的取值可以取一下值:文件權限應該爲(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 權限,代表其他用戶具有可執行的權限。
open 返回的文件描述符一定是最小的未被使用的描述符。
2. close 函數
用於關閉已打開的文件。
頭文件: #include <unistd.h>
函數原型: int close(int fd);
返回值: 0(成功)或者 -1(出錯)
fd: 是要關閉的文件描述符。
進程結束時,該進程打開的所有文件都會自動被內核(kernel)關閉。
//文件打開與關閉2008.12.06
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
#include<stdio.h>
int main(void)
{
int fd;
//調用open,以可讀寫方式打開
if((fd=open("/tmp/hello1.c",O_CREAT|O_TRUNC|O_RDWR,0700))<0){
perror("open:");
exit(1);
}
else{
printf("open file:hello1.c %d\n",fd);
}
//close
if(close(fd)<0){
perror("close:");
exit(1);
}
else{
printf("close hello1.c\n");
}
exit(0);
}
(3)read函數(讀取文件中指定大小的數據)
#include<unistd.h>
ssize_t read(int fd,void *buf,size_t count);
參數:
fd:將要讀取的數據的文件描述符
buf:所要讀取到的數據的內存緩衝
count:需要讀取的數據量
返回說明:
成功執行時,返回所讀取的數據量,如果讀到文件的末尾則返回0。失敗的時候返回-1。
(4)write()函數
寫函數write
ssize_t write(int fd,const void *buf,size_t nbytes)
write函數將buf中的nbytes字節內容寫入文件描述符fd.成功時返回寫的字節數.失敗時返回-1. 並設置errno變量. 在網絡程序中,當我們向套接字文件描述符寫時有倆種可能.
1)write的返回值大於0,表示寫了部分或者是全部的數據.
2)返回的值小於0,此時出現了錯誤.我們要根據錯誤類型來處理. 如果錯誤爲EINTR表示在寫的時候出現了中斷錯誤.
(5)lseek函數:爲一個打開的文件設置其偏移量
表頭文件
#include<sys/types.h>
函數的定義:off_t lseek(int fildes,off_t offset ,int whence);
函數說明:每一個已打開的文件都有一個讀寫位置,當打開文件時通常其讀寫位置是指向文件開頭,若是以附加的方式打開文件(如O_APPEND),則讀寫位置會指向文件尾。當read()或write()時,讀寫位置會隨之增加,lseek()便是用來控制該文件的讀寫位置。參數fildes 爲已打開的文件描述詞,參數offset 爲根據參數whence來移動讀寫位置的位移數。
參數:
whence爲下列其中一種:(SEEK_SET,SEEK_CUR和SEEK_END和依次爲0,1和2).
SEEK_SET 將讀寫位置指向文件頭後再增加offset個位移量。 SEEK_CUR 以目前的讀寫位置往後增加offset個位移量。 SEEK_END 將讀寫位置指向文件尾後再增加offset個位移量。 當whence 值爲SEEK_CUR 或SEEK_END時,參數offet允許負值的出現。 下列是教特別的使用方式: 1) 欲將讀寫位置移到文件開頭時: lseek(int fildes,0,SEEK_SET); 2) 欲將讀寫位置移到文件尾時: lseek(int fildes,0,SEEK_END); 3) 想要取得目前文件位置時: lseek(int fildes,0,SEEK_CUR);
返回值:
當調用成功時則返回目前的讀寫位置,也就是距離文件開頭多少個字節。若有錯誤則返回-1,errno 會存放錯誤代碼。
附加說明:
Linux系統不允許lseek()對tty裝置作用,此項動作會令lseek()返回ESPIPE。
(6)dup()、dup2()函數:功能就是複製文件描述符
(7)fsync()函數:fsync函數,將文件數據同步到硬盤
功能描述:
系統調用fsync將所有已寫入文件描述符fd的數據真正的寫道磁盤或者其他下層設備上。
用法:
#include <unistd.h>
int fsync(int fd);
#ifdef _POSIX_SYNCHRONIZED_IO
int fdatasysnc(int fd);
#endif
參數:
fd:文件描述符。
返回說明:
成功執行時,返回0。失敗返回-1,errno被設爲以下的某個值
EBADF: 文件描述詞無效
EIO : 讀寫的過程中發生錯誤
EROFS, EINVAL:文件所在的文件系統不支持同步
sync(將緩衝區數據寫回磁盤)
相關函數 :fsync
表頭文件 :#include<unistd.h>
定義函數 :int sync(void)
函數說明 :sync()負責將系統緩衝區數據寫回磁盤,以確保數據同步。
返回值 :成功的是時候返回0。
(9)fcntl()函數:用來改變已打開文件的性質
fcntl
函數語法要點
所需頭文件
#include <unistd.h>函數原型 :int fcnt1(int fd, int cmd, struct flock *lock)
#include <fcntl.h>
fd: 文件描述符
cmd: F_DUPFD:複製文件描述符
F_GETFD:獲得 fd 的 close-on-exec 標誌,若標誌未設置,則文件經過 exec函數之後仍保持打開狀態
F_SETFD:設置 close-on-exec 標誌,該標誌以參數 arg 的 FD_CLOEXEC 位決定
F_GETFL:得到 open 設置的標誌
F_SETFL:改變 open 設置的標誌
F_GETFK:根據 lock 描述,決定是否上文件鎖
F_SETFK:設置 lock 描述的文件鎖
F_SETLKW:這是 F_SETLK 的阻塞版本(命令名中的 W 表示等待(wait) 。)如果存在其他鎖,則調用進程睡眠;如果捕捉到信號則睡眠中斷
F_GETOWN:檢索將收到 SIGIO 和 SIGURG 信號的進程號或進程組號
F_SETOWN:設置進程號或進程組號