1. 程式人生 > >檔案操作——C庫呼叫與Linux系統呼叫區別

檔案操作——C庫呼叫與Linux系統呼叫區別

     Linux下對檔案操作有兩種方式:系統呼叫(system call)和庫函式呼叫(Library functions)。系統呼叫實際上就是指最底層的一個呼叫,在linux程式設計裡面就是底層呼叫的意思,面向的是硬體。而庫函式呼叫則面向的是應用開發的,相當於應用程式的api,採用這樣的方式有很多種原因,第一:雙緩衝技術的實現。第二,可移植性。第三,底層呼叫本身的一些效能方面的缺陷。第四:讓api也可以有了級別和專門的工作面向。

【庫函式呼叫——緩衝檔案系統】 

       緩衝檔案系統的特點是:在記憶體開闢一個“緩衝區”,為程式中的每一個檔案使用。

       當執行讀檔案的操作時,從磁碟檔案將資料先讀入記憶體“緩衝區”,裝滿後再從記憶體“緩衝區”依此讀入接收的變數。執行寫檔案的操作時,先將資料寫入記憶體“緩衝區”,待記憶體“緩衝區”裝滿後再寫入檔案。由此可以看出,記憶體 “緩衝區”的大小,影響著實際操作外存的次數,記憶體“緩衝區”越大,則操作外存的次數就少,執行速度就快、效率高。一般來說,檔案“緩衝區”的大小隨機器而定。

        緩衝檔案系統是藉助檔案結構體指標來對檔案進行管理,通過檔案指標來對檔案進行訪問,既可以讀寫字元、字串、格式化資料,也可以讀寫二進位制資料

       C庫呼叫就是屬於緩衝檔案系統,例如:fopen, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind等是帶緩衝的。


【系統呼叫——非緩衝檔案系統】 
        非緩衝檔案系統依賴於作業系統,通過作業系統的功能對檔案進行讀寫,是系統級的輸入輸出,它使用檔案描述符來表示檔案,只能讀寫二進位制檔案,但效率高、速度快

。Linux系統呼叫就屬於非緩衝檔案系統,例如:open, close, read, write, getc, getchar, putc, putchar 等是不帶緩衝的。

        檔案描述符是一些小數值,你可以通過它們訪問的開啟的檔案裝置,而有多少檔案描述符可用取決於系統的配置情況。但是當一個程式開始執行時,它一般會有3個已經開啟的檔案描述符,就是

0:標準輸入

1:標準輸出

2:標準錯誤

        那些數學(即0、1、2)就是檔案描述符,因為在Linux上一切都是檔案,所以標準輸入(stdin),標準輸出(stdout)和標準錯誤(stderr)也可看作檔案來對待。

一、系統呼叫——非緩衝檔案系統


A、open系統呼叫
open函式的原型為:

int open(const char *path, int oflags);
int open(const char *path, int oflags, mode_t mode);
引數說明:

path,是包括路徑的完整檔名,

oflags是檔案訪問模式(即是什麼方式開啟檔案,只讀、只寫還是可讀並可寫等),

mode用於設定檔案的訪問許可權。具體的可選引數,可以自己檢視手冊頁,這裡不一一詳述。

返回值說明:

         open建立了一條到檔案或裝置的訪問路徑,如果呼叫成功,返回一個可以被read、write等其他系統呼叫的函式使用的檔案描述符,而且這個檔案描述是唯一的,不與任何其他執行中的程序共享,在失敗時返回-1,並設定全域性變數errno來指明失明的原因。


B、write系統呼叫
write函式的原型為:

size_t write(int fildes, const void *buf, size_t nbytes);

函式說明:

        write的作用是把緩衝區buf的前nbytes個位元組寫入到檔案描述符fildes關聯的檔案中,返回實際寫入的位元組數。返回0表示沒有寫入任何資料,返回-1表示呼叫中出現了錯誤,錯誤程式碼儲存在errno中。
注:fildes一定要是在open呼叫中返回的建立的檔案描述符,或者是0、1、2等標準輸入、輸出或標準錯誤。

C、read系統呼叫
read函式的原型為:

size_t read(int fildes, void *buf, size_t nbytes);

函式說明:

        read系統呼叫的作用是從與檔案描述符相關的檔案裡讀入nbytes個位元組的資料,並把它們放到資料區buf中,返回讀入的位元組數,失敗時返回-1。

D、close系統呼叫
close呼叫的函式原型為:
int close(int fildes);

函式說明:

        close函式的作用是終於檔案描述符fildes一其對應的檔案之間的關聯。

二、庫函式呼叫——緩衝檔案系統

A、fopen庫函式 fopen庫函式的原型為:
FILE* fopen(const char *filename, const char *mode);
函式說明:        與底層系統呼叫open類似,成功時返回一個非空指標。失敗時返回NULL。 B、fread庫函式 fread庫函式的原型為:
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
函式說明:       與底層呼叫read相似,其作用是從stream讀取nitems個長度為size的資料到ptr所指向的緩衝區中。返回值是成功讀到緩衝區中的記錄個數。 注:stream為用fopen函式返回的檔案結構指標。 C、fwrite庫函式 fwrite庫函式的原型:
size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream);
函式說明:        與底層呼叫write相似,其作用是從ptr指向的緩衝區中讀取nitems個長度為size到資料,並把它們寫到stream所對應的檔案中。 D、fclose庫函式 fclose庫函式的原型為:
int fclose(FILE *stream);
函式說明:        與系統呼叫close相似,其作用是關閉指定的檔案流stream。

例項:

#include<stdio.h> 
main() 
{ 
FILE *fp; 
char ch; 
if((fp=fopen("d:\\jrzh\\example\\c1.txt","rt"))==NULL) 
{ 
printf("\nCannot open file strike any key exit!"); 
getch(); 
exit(1); 
} 
ch=fgetc(fp); 
while(ch!=EOF) 
{ 
putchar(ch); 
ch=fgetc(fp); 
} 
fclose(fp);

附:

C庫檔案操作標準庫函式彙總:

    檔案的開啟操作        fopen 開啟一個檔案  

    檔案的關閉操作        fclose 關閉一個檔案
    檔案的讀寫操作        fgetc 從檔案中讀取一個字元  

              fputc 寫一個字元到檔案中去   
              fgets 從檔案中讀取一個字串   

              fputs 寫一個字串到檔案中去
              fprintf 往檔案中寫格式化資料
              fscanf 格式化讀取檔案中資料
              fread 以二進位制形式讀取檔案中的資料
              fwrite 以二進位制形式寫資料到檔案中去
              getw 以二進位制形式讀取一個整數
              putw 以二進位制形式存貯一個整數

     檔案狀態檢查函式      feof 檔案結束
              ferror 檔案讀/寫出錯
              clearerr 清除檔案錯誤標誌
              ftell 瞭解檔案指標的當前位置

  檔案定位函式              rewind 反繞
              fseek 隨機定位

【區別】

1、本質:緩衝與非緩衝;

2、操作:系統呼叫通過檔案描述符來操作檔案,而庫函式通過檔案指標操作檔案;

                系統呼叫只能以二進位制的形式讀寫檔案,而庫函式可以以二進位制、字元、字串、格式化資料讀寫檔案;

3、效率:系統呼叫效率更高。