日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Linux文件操作的主要接口API及相關(guān)細節(jié)

 孤獨一兵 2016-11-21

操作系統(tǒng)API:

1、API是一些函數(shù),這些函數(shù)是由linux系統(tǒng)提供支持的,由應(yīng)用層程序來使用,應(yīng)用層程序通過調(diào)用API來調(diào)用操作系統(tǒng)中的各種功能,來干活

文件操作的一般步驟:

1、在linux系統(tǒng)中要操作一個文件,一般是先open打開一個文件,得到一個文件描述符,然后對文件進行讀寫操作(或其他操作),最后close關(guān)閉文件即可

2、文件平時是存在塊設(shè)備中的文件系統(tǒng)中的,我們把這種文件叫靜態(tài)文件。當我們?nèi)pen打開一個文件時,linux內(nèi)核做的操作包括:內(nèi)核在進程中建立了一個打開文件的數(shù)據(jù)結(jié)構(gòu),記錄下我們打開的這個文件;內(nèi)核在內(nèi)存中申請一段內(nèi)存,并且將靜態(tài)文件的內(nèi)容從塊設(shè)備中讀取到內(nèi)存中特定地址管理存放(叫動態(tài)文件)。打開文件后,以后對這個文件的讀寫操作,都是針對內(nèi)存中這一份動態(tài)文件的,而并不是針對靜態(tài)文件的。當我們對動態(tài)文件進行讀寫后,此時內(nèi)存中的動態(tài)文件和塊設(shè)備中的靜態(tài)文件就不同步了,當我們close關(guān)閉動態(tài)文件時,close內(nèi)部內(nèi)核將內(nèi)存中的動態(tài)文件的內(nèi)容去更新(同步)塊設(shè)備中的靜態(tài)文件。

3、為什么要這么設(shè)計?

以為塊設(shè)備本身有讀寫限制(回憶NnadFlash、SD等塊設(shè)備的讀寫特征),本身對塊設(shè)備進行操作非常不靈活。而內(nèi)存可以按字節(jié)為單位來操作,而且可以隨機操作(內(nèi)存就叫RAM,random),很靈活。所以內(nèi)核設(shè)計文件操作時就這么設(shè)計了

文件描述符:

1、文件描述符其實實質(zhì)是一個數(shù)字,這個數(shù)字在一個進程中表示一個特定的含義,當我們open打開一個文件時,操作系統(tǒng)在內(nèi)存中構(gòu)建了一些數(shù)據(jù)結(jié)構(gòu)來表示這個動態(tài)文件,然后返回給應(yīng)用程序一個數(shù)字作為文件描述符,這個數(shù)字就和我們內(nèi)存中維護這個動態(tài)文件的這些數(shù)據(jù)結(jié)構(gòu)掛鉤綁定上了,以后我們應(yīng)用程序如果要操作這一個動態(tài)文件,只需要用這個文件描述符進行區(qū)分。

2、文件描述符的作用域就是當前進程,出了當前進程這個文件描述符就沒有意義了

實時查man手冊

(1)當我們寫應(yīng)用程序時,很多API原型都不可能記得,所以要實時查詢,用man手冊

(2)man 1 xx查linux shell命令,man 2 xxx查API, man 3 xxx查庫函數(shù)

讀取文件內(nèi)容

ssize_t read(int fd, void *buf, size_t count);

fd表示要讀取哪個文件,fd一般由前面的open返回得到

buf是應(yīng)用程序自己提供的一段內(nèi)存緩沖區(qū),用來存儲讀出的內(nèi)容

count是我們要讀取的字節(jié)數(shù)

返回值ssize_t類型是linux內(nèi)核用typedef重定義的一個類型(其實就是int),返回值表示成功讀取的字節(jié)數(shù)。

exit、_exit、_Exit退出進程

(1)當我們程序在前面步驟操作失敗導(dǎo)致后面的操作都沒有可能進行下去時,應(yīng)該在前面的錯誤監(jiān)測中結(jié)束整個程序,不應(yīng)該繼續(xù)讓程序運行下去了。

(2)我們?nèi)绾瓮顺龀绦颍?/p>

第一種;在main用return,一般原則是程序正常終止return 0,如果程序異常終止則return -1。

第一種:正式終止進程(程序)應(yīng)該使用exit或者_exit或者_Exit之一

open函數(shù)的flag詳解:

讀寫權(quán)限:O_RDONLY O_WRONLY O_RDWR

O_RDONLY就表示以只讀方式打開,

O_WRONLY表示以只寫方式打開,

O_RDWR表示以可讀可寫方式打開

當我們附帶了權(quán)限后,打開的文件就只能按照這種權(quán)限來操作

打開存在并有內(nèi)容的文件時:O_APPEND、O_TRUNC

O_APPEND屬性去打開文件時,如果這個文件中本來是有內(nèi)容的,則新寫入的內(nèi)容會接續(xù)到原來內(nèi)容的后面;

O_TRUNC屬性去打開文件時,如果這個文件中本來是有內(nèi)容的,則原來的內(nèi)容會被丟棄

1 fd = open('a.txt', O_RDWR | O_APPEND | O_TRUNC); 2 if (-1 == fd) // 有時候也寫成: (fd < 0) 3 { 4 printf('文件打開錯誤\n'); 5 // return -1; 6 _exit(-1); 7 } 8 else 9 {10 printf('文件打開成功,fd = %d.\n', fd);11 }

打開不存在的文件時:O_CREAT、O_EXCL

open中加入O_CREAT后,不管原來這個文件存在與否都能打開成功,如果原來這個文件不存在則創(chuàng)建一個空的新文件,如果原來這個文件存在則會重新創(chuàng)建這個文件,原來的內(nèi)容會被消除掉;

O_EXCL標志和O_CREAT標志結(jié)合使用時,則沒有文件時創(chuàng)建文件,有這個文件時會報錯提醒我們;

open函數(shù)在使用O_CREAT標志去創(chuàng)建文件時,可以使用第三個參數(shù)mode來指定要創(chuàng)建的文件的權(quán)限。mode使用4個數(shù)字來指定權(quán)限的,其中后面三個很重要,對應(yīng)我們要創(chuàng)建的這個文件的權(quán)限標志。譬如一般創(chuàng)建一個可讀可寫不可執(zhí)行的文件就用0666

1 fd = open('a.txt', O_RDWR | O_CREAT | O_EXCL, 0666); 2 if (-1 == fd) // 有時候也寫成: (fd < 0) 3 { 4 perror('文件打開錯誤'); 5 _exit(-1); 6 } 7 else 8 { 9 printf('文件打開成功,fd = %d.\n', fd);10 }

O_NONBLOCK

(1)阻塞與非阻塞。如果一個函數(shù)是阻塞式的,則我們調(diào)用這個函數(shù)時當前進程有可能被卡住(阻塞住,實質(zhì)是這個函數(shù)內(nèi)部要完成的事情條件不具備,當前沒法做,要等待條件成熟),函數(shù)被阻塞住了就不能立刻返回;如果一個函數(shù)是非阻塞式的那么我們調(diào)用這個函數(shù)后一定會立即返回,但是函數(shù)有沒有完成任務(wù)不一定。

(2)阻塞和非阻塞是兩種不同的設(shè)計思路,并沒有好壞??偟膩碚f,阻塞式的結(jié)果有保障但是時間沒保障;非阻塞式的時間有保障但是結(jié)果沒保障。

(3)操作系統(tǒng)提供的API和由API封裝而成的庫函數(shù),有很多本身就是被設(shè)計為阻塞式或者非阻塞式的,所以我們應(yīng)用程度調(diào)用這些函數(shù)的時候心里得非常清楚。

(4)我們打開一個文件默認就是阻塞式的,如果你希望以非阻塞的方式打開文件,則flag中要加O_NONBLOCK標志。

(5)只用于設(shè)備文件,而不用于普通文件。

errno和perror

(1)errno就是error number,意思就是錯誤號碼。linux系統(tǒng)中對各種常見錯誤做了個編號,當函數(shù)執(zhí)行錯誤時,函數(shù)會返回一個特定的errno編號來告訴我們這個函數(shù)到底哪里錯了。

(2)linux系統(tǒng)提供了一個函數(shù)perror(意思print error),perror函數(shù)內(nèi)部會讀取errno并且將這個不好認的數(shù)字直接給轉(zhuǎn)成對應(yīng)的錯誤信息字符串,然后print打印出來。

read和write的count

(1)count和返回值的關(guān)系:count參數(shù)表示我們想要寫或者讀的字節(jié)數(shù),返回值表示實際完成的要寫或者讀的字節(jié)數(shù)。實現(xiàn)的有可能等于想要讀寫的,也有可能小于(說明沒完成任務(wù))

(2)count再和阻塞非阻塞結(jié)合起來,就會更加復(fù)雜。如果一個函數(shù)是阻塞式的,則我們要讀取30個,結(jié)果暫時只有20個時就會被阻塞住,等待剩余的10個可以讀。

(3)有時候我們寫正式程序時,我們要讀取或者寫入的是一個很龐大的文件(譬如文件有2MB),我們不可能把count設(shè)置為2*1024*1024,而應(yīng)該去把count設(shè)置為一個合適的數(shù)字(譬如2048、4096),然后通過多次讀取來實現(xiàn)全部讀完。

1 ret = write(fd, writebuf, strlen(writebuf)); 2 if (ret < 0) 3 { 4 //printf('write失敗.\n'); 5 perror('write失敗'); 6 _exit(-1); 7 } 8 else 9 {10 printf('write成功,寫入了%d個字符\n', ret);11 }

文件IO效率和標準IO

(1)文件IO就指的是open、close、write、read等API函數(shù)構(gòu)成的一套用來讀寫文件的體系,這套體系可以很好的完成文件讀寫,但是效率并不是最高的。

(2)應(yīng)用層C語言庫函數(shù)提供了一些用來做文件讀寫的函數(shù)列表,叫標準IO。標準IO由一系列的C庫函數(shù)構(gòu)成(fopen、fclose、fwrite、fread),這些標準IO函數(shù)其實是由文件IO封裝而來的(fopen內(nèi)部其實調(diào)用的還是open,fwrite內(nèi)部還是通過write來完成文件寫入的)。標準IO加了封裝之后主要是為了在應(yīng)用層添加一個緩沖機制,這樣我們通過fwrite寫入的內(nèi)容不是直接進入內(nèi)核中的buf,而是先進入應(yīng)用層標準IO庫自己維護的buf中,然后標準IO庫自己根據(jù)操作系統(tǒng)單次write的最佳count來選擇好的時機來完成write到內(nèi)核中的buf(內(nèi)核中的buf再根據(jù)硬盤的特性來選擇好的實際去最終寫入硬盤中)。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多