linux下C語言對(duì)于文件的操作,我們會(huì)經(jīng)常用到fopen(),fclose(),fwrite(),fread(),fgets()等一系列庫(kù)函數(shù),基本和是和windows下學(xué)習(xí)C語言一樣的,其實(shí)這些庫(kù)函數(shù)就是在linuxx下對(duì)系統(tǒng)調(diào)用函數(shù)的封裝,因此這里只介紹系統(tǒng)函數(shù)下的文件操作函數(shù)。
(一).open()打開文件
#include #include #includeint open(const char *pathname, int flags);
參數(shù)1:pathname,文件所在路徑
參數(shù)2:flags,文件權(quán)限,相對(duì)于程序進(jìn)程
常見宏為:O_WRONLY,O_RDONLY,O_RDWR,O_EXCL,O_APPEND,O_DUMP
參數(shù)3:mode,當(dāng)創(chuàng)建文件時(shí)候使用,一般為umask的值。
返回值: 成功返回文件描述符,否則返回-1.
?。ǘヽlose,關(guān)閉一個(gè)文件。參數(shù)為文件描述符
#includeint close(int fd);
?。ㄈ﹚rite,向文件中寫數(shù)據(jù)
#includessize_t write(int fd, const void *buf, size_t count);
fd: 文件描述符
buf:存儲(chǔ)將要寫的數(shù)據(jù)
count: 寫入的長(zhǎng)度,以字節(jié)為單位
返回值:寫入成功時(shí),返回寫入的字符長(zhǎng)度,否則返回-1。
(四)read,讀文件中數(shù)據(jù)
#includessize_t read(int fd, void *buf, size_t count);
fd: 文件描述符
buf:存儲(chǔ)將要讀入的數(shù)據(jù)
count: 讀出的長(zhǎng)度,以字節(jié)為單位
返回值:讀成功時(shí),返回讀出的字符長(zhǎng)度,否則返回-1。
例如:
#include
?。ㄎ澹﹍seek,修改文件偏移量
#include #include
fd: 文件描述符
offset:將要偏移 的字節(jié)數(shù)。
whence:從那開始偏移,宏定義如下:
SEEK_END 文件末尾
SEEK_CUR 當(dāng)前偏移量位置
SEEK_SET 文件開頭位置
注意:當(dāng)偏移量大于文件長(zhǎng)度時(shí),產(chǎn)生空洞,空洞是由所設(shè)置的偏移量超過文件尾端,并寫了一些數(shù)據(jù)造成了,其從原文件尾端到新偏移的位置之間即是產(chǎn)生的空洞。空洞不占用磁盤空間,可以使用:
du filename #查看文件所占實(shí)際磁盤空間ls filename #實(shí)際文件的大小
例如:
#include#include#include#include #include #include#define BUFF 12int 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 ”);exit(EXIT_FAILURE);}if( write(fd,str1,BUFF) == -1 ){perror(“write fial fail ”);exit(EXIT_FAILURE);}if( lseek(fd,1024,SEEK_END) == -1 ){perror(“l(fā)seek fail ”);}write(fd,str2,BUFF);return 0;}
?。?a target="_blank">access 判斷文件是否具有讀,寫,可執(zhí)行或者是否存在
#includeint access(const char *pathname, int mode);
pathname: 文件名
mode 可以選擇以下宏:
F_OK 文件是否存在
R_OK 文件否具有讀權(quán)限
X_OK 文件否具有可執(zhí)行權(quán)限
W_OK 文件否具有寫權(quán)限
返回值:滿足mode中的參數(shù)并且正確執(zhí)行則返回0 ,否則返回-1。
?。ㄆ撸ヾup或dup2,創(chuàng)建一個(gè)文件描述符,其指向同一個(gè)文件表
#includeint dup(int oldfd);
oldfd:原來的文件描述符
newfd:指定新的文件描述符數(shù)值,如果該描述已經(jīng)存在則先將其關(guān)閉,若oldfd等于newfd,ze返回newfd,而不關(guān)閉。
在此簡(jiǎn)單介紹一下文件的內(nèi)核結(jié)構(gòu):首先計(jì)算機(jī)系統(tǒng)中有一個(gè)進(jìn)程表,其中的每個(gè)進(jìn)程表項(xiàng),該表項(xiàng)中有一個(gè)打開文件描述符表,該打開的文件描述表中有很多文件描述符表項(xiàng),每項(xiàng)包括兩部分:文件描述符標(biāo)志與文件指針,其中文件指針指向一個(gè)文件表,文件表中存放著文件的狀態(tài)標(biāo)志即是否可讀是否可寫,當(dāng)前文件的偏移量,還有一個(gè)v節(jié)點(diǎn)指針,指針v節(jié)點(diǎn)指針指向一個(gè)v節(jié)點(diǎn)表,v節(jié)點(diǎn)表主要存放文件的所有者,文件長(zhǎng)度,文件的設(shè)備以及文件實(shí)際數(shù)據(jù)塊在磁盤上的位置等一系列信息??赡苓@樣描不太清楚,下面用一張圖來描述:
(八)sync與fsync
?。▽?duì)于以下會(huì)主要是針對(duì)的內(nèi)核緩沖)由于io操作會(huì)首先將數(shù)據(jù)放入內(nèi)核緩沖區(qū),所以在寫的時(shí)候如果出現(xiàn)系統(tǒng)故障則緩沖區(qū)的數(shù)據(jù)可能會(huì)丟失,所以為了防止這種情況發(fā)生,以上兩個(gè)函數(shù)使得內(nèi)核緩沖區(qū)的數(shù)據(jù)立即寫入磁盤。
#includevoid sync(void);將所有緩沖排入寫隊(duì)列,然后立即返回int fsync(int fd);將所有緩沖排入寫隊(duì)列,直到該緩沖去的數(shù)據(jù)寫入磁盤后才返回。int fdatasync(int fd);幾乎和fsync函數(shù)相同,只是fdatasync(int fd)函數(shù)只影響數(shù)據(jù)部分,而fsync還會(huì)同步更新文件的屬性。
(九)fcntl函數(shù),該函數(shù)可以改變已經(jīng)發(fā)開文件的性質(zhì)
#include#includeint fcntl(int fd, int cmd, 。.. /* arg */ );
fd:文件描述符
cmd 指明該函數(shù)執(zhí)行什么功能
F_DUPFD 賦值文件描述符,功能相當(dāng)于dup和dup2函數(shù)。例如:
dup(fd)等價(jià)于
fcntl(fd,F(xiàn)_DUPFD,0)
dup2(oldfd,newfd)等價(jià)于
close(newfd);
fcntl(oldfd,F(xiàn)_DUPFD,newfd);
F_GETFD 的到文件描述符標(biāo)志,當(dāng)前之定義一個(gè)文件描述符標(biāo)志,F(xiàn)D_CLOSEEXEC.此時(shí)第三個(gè)參數(shù)被忽視。
F_SETFD 設(shè)置文件描述符標(biāo)志,設(shè)置的值是函數(shù)的第三個(gè)參數(shù),其一般可設(shè)置為0表示關(guān)閉,1表示打開。
F_SETFL 設(shè)置文件狀態(tài)標(biāo)志,其值放在函數(shù)的第三個(gè)參數(shù),和open函數(shù)第二個(gè)參數(shù)的值一樣的。
F_GETFL 得到文件狀態(tài)標(biāo)志。此時(shí)第三個(gè)參數(shù)被忽視。
arg 可選參數(shù),根據(jù)第二個(gè)參數(shù)填寫。
返回值:出錯(cuò)返回-1,否則哈返達(dá)到的標(biāo)志。
例如:
#include#include#include#includeint main(int argc,char * argv[]){int fd;int val=3;if( (fd = open(argv[1],O_RDWR|O_APPEND)) == -1 )//測(cè)試一下是否可以同時(shí)檢測(cè)出文件的讀寫屬性{exit(2);}if( val = fcntl(fd,F(xiàn)_GETFL,0) == -1 ){exit(1);}printf(“%d ”,val);printf(“%d %d %d ”,O_RDONLY,O_WRONLY,O_RDWR);int n = val & O_ACCMODE;if( n == O_RDONLY)printf(“read ”);if(O_WRONLY & val )printf(“write ”);if( n == O_RDWR)printf(“read and write ”);}
?。ㄊ┳詈笤僬f一下Linux緩沖的問題吧
linux中有兩個(gè)級(jí)別的緩沖:IO緩沖與內(nèi)核緩沖
?。?)IO緩沖:對(duì)于標(biāo)準(zhǔn)IO操作,都會(huì)有一個(gè)緩沖區(qū),當(dāng)用戶想要寫數(shù)據(jù)時(shí),首先將數(shù)據(jù)寫入緩沖區(qū),待緩沖區(qū)滿之后才能調(diào)用系統(tǒng)函數(shù)寫入內(nèi)核緩沖區(qū)。當(dāng)用戶想讀取數(shù)據(jù)時(shí),首先向內(nèi)核讀取一定的數(shù)據(jù)放入IO緩沖區(qū),讀操作從緩沖區(qū)中讀數(shù)據(jù),當(dāng)讀完IO緩沖區(qū)的數(shù)據(jù)時(shí),才能再讀取數(shù)據(jù)到IO緩沖區(qū)。
目的:減少對(duì)磁盤的讀寫次數(shù),提高工作效率。
(2)內(nèi)核緩沖區(qū):操作系統(tǒng)內(nèi)核部分也有緩沖,其與IO緩沖區(qū)是不同的,其主要區(qū)別用一張圖表示:
評(píng)論
查看更多