Linux系統呼叫和ANSI C檔案操作的區別

2021-07-05 16:25:36 字數 3541 閱讀 2872

一、在linux下對檔案操作有兩種方式:linux系統呼叫和ansi c檔案操作。

1、linux系統呼叫呼叫常用於i/o檔案操作,系統呼叫常用的函式有open、close、read、write、lseek、ulink等。

2、 ansi c檔案操作

ansi c檔案操作方法是所有作業系統通用的檔案操作方法,它的操作是被緩衝過的被修改的檔案並不會立即反應到磁碟中,它在記憶體中開闢乙個「緩衝區」,為程式中的每乙個檔案操作所使用,當執行讀檔案的操作時,從磁碟檔案中將資料先讀入記憶體「緩衝區「,裝滿後再從記憶體「緩衝區」依次讀入接收的資料。這種檔案操作方式又被稱作流式檔案操作。ansi c檔案操作常用的函式有fopen、fclose、fread、fwrite、fseek、ftell、rewind、fgetc、fputc、fgets、fputs及remove等

三、下面用兩個函式說明linux系統呼叫和ansi c檔案操作的區別。

1、由於緩衝區的存在,因此流中的資料與對應檔案的資料可能不一致,當系統掉電時,檔案若沒有及時close(),緩衝區的資料就會丟失,為了同步緩衝區,此時可以呼叫fflush()函式實現。

fflush()函式需要的標頭檔案:

#include

函式原型:

int fflush(file *stream);

引數說明: 

  stream:檔案控制代碼。

返回值:

  成功返回0;

  失敗返回eof。

應用示例:

fflush函式應用示例**如程式清單1所示。示例程式用來用while死迴圈模擬掉電狀態,開啟或建立當前目錄下的「./test_2」檔案並寫入「hello,world!」字串。當呼叫fflush函式後,檔案成功寫入「hello,world!」字串,否則將未寫入該字串。

程式清單1

#include #define syncteston  0

int main(void)

else

fclose(fp);

}

說明:syncteston 為0時,程式沒有呼叫fflush(),執行e10時,程式進入while迴圈,用「ctrl」+「c」強制退出程式(模擬掉電狀態),用cat   test_2命令檢視檔案,資料此時並沒有寫入;syncteston 為1時,程式呼叫fflush(),執行e10,程式進入while,用「ctrl」+「c」強制退出程式,然後用cat  test_2檢視檔案,資料此時已經寫入。 

2、由於緩衝區的存在,為了同步緩衝區,可以呼叫fflush()實現。但是當掉電時,未呼叫fflush()時,此時緩衝區的資料仍舊會丟失。而setvbuf()函式可以修改緩衝區的工作模式,也可以解決這一問題。

setvbuf函式需要的標頭檔案:#include 函式原型:int setvbuf(file *stream,char *buf,int mode,size_t size); 

引數說明:  stream:檔案控制代碼。  buf:如果buf未null,由編譯器決定如何建立流的緩衝區,否則其應該指向一段大小為size的記憶體。  mode:指定了緩衝區的型別,_iofbf(全緩衝),_iolbj(行緩衝),_ionbf(無緩衝)。  size:指定了緩衝區的大小。如果指定乙個不帶緩衝區的流,則忽略  buf 和 size 引數。返回值:  成功返回0;  失敗返回非零值。

應用示例:setvbuf函式應用示例**如程式清單2所示。

示例程式用來用while死迴圈模擬掉電狀態,開啟或建立當前目錄下的「./test_3」檔案並寫入「hello,world!」字串。當呼叫setvbuf函式將緩衝區的型別設定為_ionbf後,檔案可以正常寫入「hello,world!」字串,否則將未寫入該字串。

#include #define sycnteston 1

int main(void)

icount = fwrite(str, 12, 1, fp);

printf("%d block(12 bytes per block) read, check it out!\n", icount);

while(1);

fclose(fp);

}

說明:測試方法同fflush()一致;setvbuf()函式如果要設定流的緩衝區,則函式必須在開啟檔案後立即呼叫,一旦操作了流,就不能再呼叫此函式了,否則結果不可預知。非緩衝的檔案操作訪問方式,每次對檔案進行一次讀寫操作時,都需要使用linux系統呼叫來處理此操作,執行一次linux系統呼叫將涉及到cpu狀態的切換,即從使用者空間切換到核心空間,實現程序上下文的切換,這將損耗一定的cpu時間,頻繁的磁碟訪問對程式的執行效率會造成較大的影響。

除此以外,setbuf也可以實現setvbuf用法,

需要的標頭檔案:

#include 函式原型:

int setbuf(file *stream,char *buf);

引數說明:

  stream:檔案控制代碼。

  buf:引數buf須指向乙個長度為bufsiz的緩衝區,如果將buf設定為null,則

關閉緩衝區。

返回值:

  成功返回0;

  失敗返回非零值。

四、通過以上內容,總結linux系統呼叫和ansi c檔案操作的區別。

1、 linux系統呼叫

linux系統呼叫實際上就是指最底層的乙個呼叫,在linux程式設計裡面就是底層呼叫,面向的是硬體。而ansi c則是庫函式呼叫,是面向的是應用開發的,相當於應用

程式的api(應用程式介面)。我覺得採用這樣的方式有以下幾個原因:

第一,雙緩衝技術的實現;

第二,可移植性的考慮;

第三,底層呼叫本身的一些效能缺陷(如頻繁擦寫影響檔案儲存介質的壽命);

第四,讓api也可以有具體分層和專門的應用方向。

linux系統呼叫是作業系統相關的,因此一般沒有跨作業系統的可移植性。linux系統呼叫發生在核心空間,因此如果在使用者空間的一般應用程式中使用系統呼叫來進行檔案操作,會有使用者空間到核心空間切換的開銷。

事實上,即使在使用者空間使用ansi c檔案操作,因為檔案總是存在於儲存介質上,因此不管是讀寫操作,都是對硬體(儲存器)的操作,都必然會引起linux系統呼叫。也就是說,ansi c檔案操作實際上是通過系統呼叫來實現的。例如c庫函式fwrite()就是通過write()系統呼叫來實現的。這樣的話,使用庫函式也有系統呼叫的開銷,為什麼不直接使用系統呼叫呢?這是因為讀寫檔案通常是大量的資料(這種大量是相對於底層驅動的系統呼叫所實現的資料操作單位而言),這時,使用ansi c檔案操作就可以大大減少系統呼叫的次數。這一結果又緣於緩衝區技術。在使用者空間和核心空間,對檔案操作都使用了緩衝區,例如用fwrite寫檔案,都是先將內容寫到使用者空間緩衝區,當使用者空間緩衝區滿或者寫操作結束時,才將使用者緩衝區的內容寫到核心緩衝區,同樣的道理,當核心緩衝區滿或寫結束時才將核心緩衝區內容寫到檔案對應的硬體媒介。

2.4.2  ansi c檔案操作

ansi c檔案操作通常用於應用程式中對一般檔案的訪問。ansi c檔案操作是系統無關的,因此可移植性好,由於ansi c檔案操作是基於c庫的,因此也就不可能用於核心空間的驅動程式中對裝置的操作。

Linux檔案操作(ANSI C)

1.檔案指標 ansi檔案操作提供了乙個檔案指標file來進行對檔案的開啟讀寫和關閉及其他訪問 它的結構體 typedef struct file 2.緩衝 緩衝目的是為了減少外部裝置的讀寫次數,同時使用緩衝能提高應用程式的讀寫效能 緩衝有三種 全緩衝 行緩衝 不帶緩衝。全緩衝 填滿才會操作 行緩衝...

Linux系統呼叫和庫函式呼叫

linux下對檔案操作有兩種方式 系統呼叫 system call 和庫函式呼叫 library functions 可以參考 linux程式設計 英文原版為 beginning linux programming 作者是neil matthew和richard stones 第三章 working...

Linux系統呼叫和庫函式呼叫

linux下對檔案操作有兩種方式 系統呼叫 system call 和庫函式呼叫 library functions 可以參考 linux程式設計 英文原版為 beginning linux programming 作者是neil matthew和richard stones 第三章 working...