linux下C語言對於文件的操做,咱們會常常用到fopen(),fclose(),fwrite(),fread(),fgets()等一系列庫函數,基本和是和windows下學習C語言同樣的,其實這些庫函數就是在linuxx下對系統調用函數的封裝,所以這裏只介紹系統函數下的文件操做函數。html
(一).open()打開文件linux
#include <sys/types.h> #include <sys/stat.h> #include int open(const char *pathname, int flags);
參數1:pathname,文件所在路徑
參數2:flags,文件權限,相對於程序進程
常見宏爲:O_WRONLY,O_RDONLY,O_RDWR,O_EXCL,O_APPEND,O_DUMP
參數3:mode,當建立文件時候使用,通常爲umask的值。
返回值: 成功返回文件描述符,不然返回-1.windows
(二)close,關閉一個文件。參數爲文件描述符async
#include int close(int fd);
(三)write,向文件中寫數據函數
#include ssize_t write(int fd, const void *buf, size_t count);
fd: 文件描述符
buf:存儲將要寫的數據
count: 寫入的長度,以字節爲單位
返回值:寫入成功時,返回寫入的字符長度,不然返回-1。學習
(四)read,讀文件中數據測試
#include ssize_t read(int fd, void *buf, size_t count);
fd: 文件描述符
buf:存儲將要讀入的數據
count: 讀出的長度,以字節爲單位
返回值:讀成功時,返回讀出的字符長度,不然返回-1。
例如:
#include操作系統
(五)lseek,修改文件偏移量指針
#include <sys/types.h> #include <unistd.h off_t lseek(int fd, off_t offset, int whence);
fd: 文件描述符
offset:將要偏移 的字節數。
whence:從那開始偏移,宏定義以下:
SEEK_END 文件末尾
SEEK_CUR 當前偏移量位置
SEEK_SET 文件開頭位置
注意:當偏移量大於文件長度時,產生空洞,空洞是由所設置的偏移量超過文件尾端,並寫了一些數據形成了,其從原文件尾端到新偏移的位置之間便是產生的空洞。空洞不佔用磁盤空間,可使用:htm
du filename #查看文件所佔實際磁盤空間 ls filename #實際文件的大小
例如:
#include #include #include #include <sys/types.h> #include <sys/stat.h> #include #define BUFF 12 int main() { char str1[BUFF] = "jigntikai"; char str2[BUFF] = "wojisuhihawe"; int fd; if ( (fd = open("a.txt",O_WRONLY|O_CREAT,0744)) = { perror("open file fail\n"); exit(EXIT_FAILURE); } if( write(fd,str1,BUFF) == -1 ) { perror("write fial fail\n"); exit(EXIT_FAILURE); } if( lseek(fd,1024,SEEK_END) == -1 ) { perror("lseek fail\n"); } write(fd,str2,BUFF); return 0; }
(六)access 判斷文件是否具備讀,寫,可執行或者是否存在
#include int access(const char *pathname, int mode);
pathname: 文件名
mode 能夠選擇如下宏:
F_OK 文件是否存在
R_OK 文件否具備讀權限
X_OK 文件否具備可執行權限
W_OK 文件否具備寫權限
返回值:知足mode中的參數而且正確執行則返回0 ,不然返回-1。
(七)dup或dup2,建立一個文件描述符,其指向同一個文件表
#include int dup(int oldfd);
oldfd:原來的文件描述符
newfd:指定新的文件描述符數值,若是該描述已經存在則先將其關閉,若oldfd等於newfd,ze返回newfd,而不關閉。
在此簡單介紹一下文件的內核結構:首先計算機系統中有一個進程表,其中的每一個進程表項,該表項中有一個打開文件描述符表,該打開的文件描述表中有不少文件描述符表項,每項包括兩部分:文件描述符標誌與文件指針,其中文件指針指向一個文件表,文件表中存放着文件的狀態標誌便是否可讀是否可寫,當前文件的偏移量,還有一個v節點指針,指針v節點指針指向一個v節點表,v節點表主要存放文件的全部者,文件長度,文件的設備以及文件實際數據塊在磁盤上的位置等一系列信息。可能這樣描不太清楚,下面用一張圖來描述:
(八)sync與fsync
(對於如下會主要是針對的內核緩衝)因爲io操做會首先將數據放入內核緩衝區,因此在寫的時候若是出現系統故障則緩衝區的數據可能會丟失,因此爲了防止這種狀況發生,以上兩個函數使得內核緩衝區的數據當即寫入磁盤。
#include void sync(void);將全部緩衝排入寫隊列,而後當即返回 int fsync(int fd);將全部緩衝排入寫隊列,直到該緩衝去的數據寫入磁盤後才返回。 int fdatasync(int fd);幾乎和fsync函數相同,只是fdatasync(int fd)函數隻影響數據部分,而fsync還會同步更新文件的屬性。
(九)fcntl函數,該函數能夠改變已經發開文件的性質
#include #include int fcntl(int fd, int cmd, ... /* arg */ );
fd:文件描述符
cmd 指明該函數執行什麼功能
F_DUPFD 賦值文件描述符,功能至關於dup和dup2函數。例如:
dup(fd)等價於
fcntl(fd,F_DUPFD,0)
dup2(oldfd,newfd)等價於
close(newfd);
fcntl(oldfd,F_DUPFD,newfd);
F_GETFD 的到文件描述符標誌,當前之定義一個文件描述符標誌,FD_CLOSEEXEC.此時第三個參數被忽視。
F_SETFD 設置文件描述符標誌,設置的值是函數的第三個參數,其通常可設置爲0表示關閉,1表示打開。
F_SETFL 設置文件狀態標誌,其值放在函數的第三個參數,和open函數第二個參數的值同樣的。
F_GETFL 獲得文件狀態標誌。此時第三個參數被忽視。
arg 可選參數,根據第二個參數填寫。
返回值:出錯返回-1,不然哈返達到的標誌。
例如:
#include #include #include #include int main(int argc,char * argv[]) { int fd; int val=3; if( (fd = open(argv[1],O_RDWR|O_APPEND)) == -1 )//測試一下是否能夠同時檢測出文件的讀寫屬性 { exit(2); } if( val = fcntl(fd,F_GETFL,0) == -1 ) { exit(1); } printf("%d\n",val); printf("%d %d %d\n",O_RDONLY,O_WRONLY,O_RDWR); int n = val & O_ACCMODE; if( n == O_RDONLY) printf("read\n"); if(O_WRONLY & val ) printf("write\n"); if( n == O_RDWR) printf("read and write\n"); }
(十)最後再說一下Linux緩衝的問題吧
linux中有兩個級別的緩衝:IO緩衝與內核緩衝
(1)IO緩衝:對於標準IO操做,都會有一個緩衝區,當用戶想要寫數據時,首先將數據寫入緩衝區,待緩衝區滿以後才能調用系統函數寫入內核緩衝區。當用戶想讀取數據時,首先向內核讀取必定的數據放入IO緩衝區,讀操做從緩衝區中讀數據,當讀完IO緩衝區的數據時,才能再讀取數據到IO緩衝區。
目的:減小對磁盤的讀寫次數,提升工做效率。
(2)內核緩衝區:操做系統內核部分也有緩衝,其與IO緩衝區是不一樣的,其主要區別用一張圖表示:
本文地址:http://www.linuxprobe.com/linux-file-i-o.html編輯:馮瑞濤,審覈員:逄增寶