Linux下檔案I O系統呼叫

2021-10-03 23:17:44 字數 4308 閱讀 8678

庫是可重用的模組 處於使用者態

系統呼叫是os提供的服務 處於核心態 不能直接呼叫 而要使用類似int 0x80的軟中斷陷入核心 所以庫函式中有很大部分是對系統呼叫的封裝。從巨集觀上說,系統呼叫時核心層,c標準庫在應用層。

檔案描述符是linux核心為了高效管理已被開啟的檔案而建立的索引,其值為乙個非負整數,而通常為小整數。而且系統執行時,系統會自動開啟三個檔案描述符,即標準輸入0,標準輸出1,標準 出錯2 。這三個檔案描述符預設存在,若新開啟的檔案描述符最小只能是3 .

在linux中,副檔名對linux核心沒有實際意義,但是可以用來人為區分不同的檔案,方便使用者使用。

.tar, .tar.gz, .tgz, .zip, .tar.bz表示壓縮檔案,

建立命令為tar, gzip, unzip等

.sh 檔案表示shell指令碼檔案

.pl 表示perl語言檔案

.py 表示python語言檔案

.conf 表示系統服務的配置檔案

.c 表示c檔案

.h 標頭檔案

.cpp 表示c++原始檔

.so 表示動態庫檔案

.a 表示靜態庫檔案

open()系統呼叫

int

open

(const

char

*path,

int oflag,..

./*mode_t mode*/

);

int   fd;

fd =

open

("text.txt"

, o_rdwr|o_creat|o_trunc,

0666);

fd =

open

("text.txt"

;

create()系統呼叫

int

create

(const

char

*path, mode_t mode)

;

該函式用來建立乙個新檔案並返回其fd。它等價於open(path, o_wronly|o_creat|o_trunc, mode);

int     fd;

fd =

create

("text.txt"

,0644

);

write()系統呼叫

ssize_t write

(int fd,

const

void

*buf, size_t nbytes)

;

write()函式用來往開啟的檔案描述符fd指向的檔案中寫入buf指向的資料,其中nbytes指定要寫入的資料大小。如果返回值 <0則說明寫入出錯,譬如嘗試往乙個唯讀的檔案中寫入則會拋錯,錯誤的原因系統會儲存到errno變數中去。如果》0則為實 際寫入的資料大小。

lseek()系統呼叫

off_t lseek

(int fd, off_t offsset,

int whence)

;

我們在從檔案裡讀出內容,或往檔案寫如內容的時候都有乙個起始位址,這個起始位址就是當前檔案偏移量,當我們對檔案 進行讀寫的時候都會使檔案偏移量往後偏移。這點就類似於我們開啟記事本開始編輯文字時的游標,我們讀或寫入時從游標 所在位置開始讀寫,每讀寫乙個位元組都會使游標往後偏移。通過lseek()這個函式我們可以調整檔案偏移量的位址。 其中 whence 可以是以下三個值:

而offset就是相對於whence 的偏移量,

譬如lseek(fd, 0, seek_set); 將檔案偏移量設定到了檔案開始的第乙個位元組上

lseek(fd, 0, seek_end); 將檔案偏移量設定到檔案最後乙個位元組上;

lseek(fd, -1, seek_end); 將檔案偏移量設定到檔案最後的倒數第乙個位元組上;

read()系統呼叫

ssize_t read

(int fd,

void

*buf, size_t nbytes)

;

read()函式用來從開啟的檔案描述符對應的檔案中讀取資料放到buf指向的記憶體空間中去,最多不要超過nbytes個位元組,這裡 的nbytes一般是buf剩餘的空間大小。如read成功,則返回實際讀到的位元組數(由nbytes或讀到檔案尾決定,其中eof巨集用 來判斷是否到了檔案尾),如果返回值小於0則表示出錯,如嘗試讀乙個沒有許可權讀的檔案時就會拋錯。

出錯處理

對linux而言絕大部分情況下,系統呼叫出錯都會返回-1,而成功則返回0或其相應返回值。linux中系統呼叫的錯誤原因都 儲存於在int errno中,errno由作業系統維護,儲存就近發生的錯誤,即下一次的錯誤碼會覆蓋掉上一次的錯誤,當然只有在 系統呼叫或者呼叫lib函式時出錯(因為有些庫函式會呼叫系統呼叫),才會置位errno。在標頭檔案「/usr/include/asmgeneric/errno-base.h」定義了常見的錯誤原因errno整形值。大家可以看看這個標頭檔案的定義,了解一下常見的錯誤原因。

因為系統呼叫出錯的原因是以整形值的形式儲存在errno中,則個整形值errno對程式設計師非常不友好,我們更多的是希望看 到字串形式的錯誤提示,這時經常用到的兩個錯誤處理函式是 perror()和strerror()。下面是這兩個函式的原型。

void perror(const char *s)

char *strerror(int errno);

其中perror()的使用方法非常簡單,只需要乙個字串引數s即可。他會將錯誤的原因列印到標準輸出上,其內容是字串s 後面緊跟 冒號和字串形式的錯誤原因。需要注意的是字串s 裡不要加換行符,因為錯誤原因裡面會帶換行。 因為perror()的使用功能比較簡單且只能列印到標準輸出上,對於要進行格式化控制的輸出或想寫入到日誌檔案中時就不能 處理了。這時我們會使用另外乙個函式strerror(),它用來將整形型別的錯誤原因errno裝換成相應的字串形式,這樣在任 何使用字串的地方我們都可以使用它。所以在今後的程式設計中,我們更多的是使用strerror()而不是perror()。

該程式將呼叫open()系統呼叫開啟乙個叫做test.txt的檔案(如 果不存在則會建立該檔案),然後呼叫write()系統呼叫將字串 msg_str 寫入到該檔案中,之後呼叫read()系統呼叫讀出該 檔案裡的內容。

#include

#include

#include

#include

#include

#include

#define bufsize 1024

#define wxj "helo xiaojuan\n"

intmain

(int argc,

char

**ar**)

printf

("open file returned file descriptor [%d]\n"

,fd);if

((rv =

write

(fd, wxj,

strlen

(wxj)))

<0)

memset

(buf,0,

sizeof

(buf));

//清零buf

lseek

(fd,0,

seek_set);

if((rv =

read

(fd, buf,

sizeof

(buf)))

<0)

printf

("read %d bytes data from file:%s\n"

, rv, buf)

; cleanup:

close

(fd)

;//用完的檔案描述符記得關閉

return0;

}

程式執行截圖:

由結果可以看出,新開啟的檔案描述符為3,為當前可用最小。寫程式時應注意將檔案偏移量移到檔案開頭去,方可讀到資料,而且寫完資料後應當關閉檔案描述符,以便下次使用。

Linux系統呼叫IO

讀檔案 ssize t read int fd,void buf,size t count 引數一 int open的返回值 引數二 void 用來存放讀取資料的記憶體的首位址 引數三 size t 讀取內容大小,單位 位元組 返回值 成功 0 讀取的位元組數 0 檔案末尾 失敗 1 寫檔案ssiz...

Linux 檔案相關系統呼叫介面(IO)

早期在寫c語言介面的時候,我們可以通過fopen來開啟乙個檔案,下面這段兩段 為例 hello.c寫檔案 1 include 2 include 3 int main 4 9 const char msg hello world n 10 int count 5 11 while count 14 ...

檔案系統之標準IO與系統呼叫IO

io操作是我們程式執行的基礎,資料在程式執行結束時需要儲存就必須使用io操作。io主要包括兩類 標準io與系統io 一 標準io 標準io是為了避免跨平台移植引起的不必要異常,指定的一系列標準函式,無論linux windows都可以使用。標準io常用api包括 fopen fwrite fread...