文件I/O
直接使用系統(tǒng)調(diào)用的缺點(diǎn):
影響系統(tǒng)性能
系統(tǒng)調(diào)用比普通函數(shù)調(diào)用開銷大,因?yàn)橄到y(tǒng)調(diào)用要進(jìn)行用戶空間和內(nèi)核空間的切換。
系統(tǒng)調(diào)用一次所能讀寫的數(shù)據(jù)量大小,受硬件的限制。
解決方案:使用帶緩沖功能的標(biāo)準(zhǔn)I/O庫(kù),以減少系統(tǒng)調(diào)用的次數(shù)。 例如: fwrite、fread、fopen、fclose、fseek、fflush
文件系統(tǒng)接口

文件系統(tǒng)緩存

標(biāo)準(zhǔn)文件訪問(wèn)方式

直接IO方式

示例:
代碼語(yǔ)言:JavaScript代碼運(yùn)行次數(shù):0運(yùn)行復(fù)制
#define _GNU_SOURCE#include <stdio.h>#include <string.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <sys>#include <sys>#include <fcntl.h>#define TOTAL 10//直接IO要考慮到硬件特性//磁盤最基本的單位是扇區(qū),一個(gè)扇區(qū)512字節(jié)#define BUF_LEN 512int writeToFile(int fd,const char* buf,int len) {int wlen = 0;if ((wlen = write(fd, buf, len)) <figure class=""><hr></figure>直接IO和標(biāo)準(zhǔn)方式進(jìn)行對(duì)比<p>**示例:**測(cè)試20s內(nèi)對(duì)同一文件的讀取次數(shù)0</p>代碼語(yǔ)言:javascript<i class="icon-code"></i>代碼運(yùn)行次數(shù):<!-- -->0<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewbox="0 0 16 16" fill="none"><path d="M6.66666 10.9999L10.6667 7.99992L6.66666 4.99992V10.9999ZM7.99999 1.33325C4.31999 1.33325 1.33333 4.31992 1.33333 7.99992C1.33333 11.6799 4.31999 14.6666 7.99999 14.6666C11.68 14.6666 14.6667 11.6799 14.6667 7.99992C14.6667 4.31992 11.68 1.33325 7.99999 1.33325ZM7.99999 13.3333C5.05999 13.3333 2.66666 10.9399 2.66666 7.99992C2.66666 5.05992 5.05999 2.66659 7.99999 2.66659C10.94 2.66659 13.3333 5.05992 13.3333 7.99992C13.3333 10.9399 10.94 13.3333 7.99999 13.3333Z" fill="currentcolor"></path></svg>運(yùn)行<svg width="16" height="16" viewbox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 15.5V3.5H14.5V15.5H4.5ZM12.5 5.5H6.5V13.5H12.5V5.5ZM9.5 2.5H3.5V12.5H1.5V0.5H11.5V2.5H9.5Z" fill="currentcolor"></path></svg>復(fù)制<pre class="prism-token token line-numbers javascript">#define _GNU_SOURCE#include <stdio.h>#include <string.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <sys>#include <sys>#include <fcntl.h>#define BUF_SIZE 512int main(int argc, char** argv) {char* buf = NULL;const char* filename = "./open_compare.txt";int fd = -1;time_t start;time_t cur;int rlen = 0;int ret = 0;static int read_total = 0;ret = posix_memalign((void**)&buf,512,BUF_SIZE);if (ret)fprintf(stderr,"posix_memalign failed.reason:%sn",strerror(errno));start = time(NULL);do {read_total++;//fd = open(filename, O_RDWR | O_DIRECT);fd = open(filename,O_RDWR);if (fd 0);close(fd);cur = time(NULL);} while ((cur-start) <p>直接IO</p> <figure class=""><img src="https://img.php.cn/upload/article/001/503/042/174506652360359.jpg" alt="【Linux】Linux文件I/O"></figure><p>標(biāo)準(zhǔn)方式</p> <p>(高速頁(yè)緩存,多次讀取速度快。)</p> <figure class=""><img src="https://img.php.cn/upload/article/001/503/042/174506652369371.jpg" alt="【Linux】Linux文件I/O"></figure><figure class=""><hr></figure>O_SYNC<figure class=""><img src="https://img.php.cn/upload/article/001/503/042/174506652331485.jpg" alt="【Linux】Linux文件I/O"></figure>緩存同步<p>為了保證磁盤系統(tǒng)與緩沖區(qū)內(nèi)容一致,Linux系統(tǒng)提供了sync,fsync,fdatasync三個(gè)函數(shù)。</p> <p>函數(shù)描述:向打開的文件寫數(shù)據(jù),成功返回寫入的字節(jié)數(shù),出錯(cuò)則返回-1。</p>代碼語(yǔ)言:javascript<i class="icon-code"></i>代碼運(yùn)行次數(shù):<!-- -->0<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewbox="0 0 16 16" fill="none"><path d="M6.66666 10.9999L10.6667 7.99992L6.66666 4.99992V10.9999ZM7.99999 1.33325C4.31999 1.33325 1.33333 4.31992 1.33333 7.99992C1.33333 11.6799 4.31999 14.6666 7.99999 14.6666C11.68 14.6666 14.6667 11.6799 14.6667 7.99992C14.6667 4.31992 11.68 1.33325 7.99999 1.33325ZM7.99999 13.3333C5.05999 13.3333 2.66666 10.9399 2.66666 7.99992C2.66666 5.05992 5.05999 2.66659 7.99999 2.66659C10.94 2.66659 13.3333 5.05992 13.3333 7.99992C13.3333 10.9399 10.94 13.3333 7.99999 13.3333Z" fill="currentcolor"></path></svg>運(yùn)行<svg width="16" height="16" viewbox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 15.5V3.5H14.5V15.5H4.5ZM12.5 5.5H6.5V13.5H12.5V5.5ZM9.5 2.5H3.5V12.5H1.5V0.5H11.5V2.5H9.5Z" fill="currentcolor"></path></svg>復(fù)制<pre class="prism-token token line-numbers javascript">#include<unistd.h>int fsync(int fd);int fdatasync(int fd);void sync(void);</unistd.h>
說(shuō)明:
sync——將所有修改過(guò)的塊緩沖區(qū)排入寫隊(duì)列,然后就返回,它并不等待實(shí)際寫磁盤操作結(jié)束。fsync——將fd對(duì)應(yīng)文件的塊緩沖區(qū)立即寫入磁盤,并等待實(shí)際寫磁盤操作結(jié)束返回。fdatasync——類似fsync,但只影響文件的數(shù)據(jù)部分。而除數(shù)據(jù)外,fsync還會(huì)同步更新文件屬性。
Linux文件IO流程圖
