Linux應用程式之檔案

2021-06-26 13:49:43 字數 4490 閱讀 8387

檔案是具有永久性儲存、按照特定位元組順序組成的乙個有序的資料的集合。

根據資料的儲存方式,可將檔案分為二進位制檔案和文字檔案,計算機的儲存在物理上是二進位制的,所以文字檔案與二進位制檔案的區別並不是物理上的,而是邏輯上的。這兩者只是在編碼層次上有差異。簡單來說,文字檔案是基於字元編碼的檔案,常見的編碼有ascii編碼,unicode編碼等。二進位制檔案是基於值編碼的檔案,你可以根據具體應用,指定某個值是什麼意思,這樣乙個過程,可以看作是自定義編碼。

linux中的七種檔案:

linux系統中任何程序在執行時,都預設開啟三個檔案:(1)標準輸入stdio (2)標準輸出stdout (3)標準出錯stderr。

linux中用open開啟檔案時會建立下面三個資料結構:

(1) 檔案描述符陣列(每個元素有兩項:前一項為檔案描述符(fd),後一項為struct file結構體指標)中,linux中檔案描述符陣列長度為1024(每個可同時開啟1024個檔案),每次開啟檔案時系統分配目前未被使用的最小的檔案描述符給開啟的檔案;

(2) struct files記錄乙個開啟的檔案的相關資訊,包括:檔案狀態標誌(open第二個引數),檔案當前偏移

量(下一次讀寫的位置),檔案讀寫許可權等。

(3) struct node記錄乙個物理上存在的檔案的相關資訊,包括檔案建立者,大小,建立時間,屬性等等。

核心為使當前程序與程序開啟的檔案建立聯絡,在程序的pcb(程序控制塊task_struct)中使用乙個成員來指向管理程序開啟檔案列表的結構體struct files_struct,而結構體中的struct file *fd_array是乙個指標陣列,指向程序所開啟的檔案的struct file。核心將這個陣列中每個成員的下標值(int型)傳遞給使用者空間來標識該開啟的檔案,該值即是檔案描述符值。每個被開啟的檔案都

對應於乙個struct file,而每個檔案只有乙個struct node。

(1) open函式:開啟和建立檔案。

#include int open(const char *pathname, int flags);

int open(const char *pathname, int flags, mode_t mode);

返回值:成功則返回檔案描述符,否則返回 -1

對於open函式而言,只有建立新檔案(檔案不存在時開啟)是才需要使用到第三個引數。

新增o_creat標誌時 若檔案不存在則自動建立檔案,此時第三個引數為操作檔案許可權。

(2) close函式:關閉檔案。

#include int close(int fd);
返回值:成功返回0,出錯返回-1並設定errno

引數fd是要關閉的檔案描述符。需要說明的是,當乙個程序終止時,核心對該程序所有尚未

關閉的檔案描述符呼叫close關閉。

(3) read函式:讀檔案

#include ssize_t read(int fd, void *buf, int nbyte);
函式說明:read()會把引數fd所指的檔案傳送nbyte個位元組到buf指標所指的記憶體中。

若引數nbyte為0,則read()不會有作用並返回0。返回值為實際讀取到的位元組數,如果返回0,

表示已到達檔案尾或無可讀取的資料。

(4) write函式:寫檔案

#include ssize_t write(int fd, void *buf, int nbyte);
函式說明:write函式把buf中nbyte寫入檔案描述符fd所指的文件,成功時返回寫的位元組數,錯誤時返回-1.

(5) lseek函式:檔案讀寫位置定位(修改struct file結構體中檔案當前偏移量的值)

#include #include off_t lseek(int fd, off_t offset, int whence);
whence的值:

seek_set: 檔案開頭

seek_cur: 檔案當前位置

seek_end: 檔案末尾

返回值:若成功返回為檔案指標相對於檔案頭的位置,若出錯為-1;

lssek(fd,10l,seek_end);//允許操作;

//此時新增的10個位元組空間存放空洞字元("\0"),空洞字元其實就是二進位制的0;

lssek(fd,-10l,seek_set);//不允許操作。

(6) fcntl函式:

更改檔案屬性

#include #include #include int fcntl(int fd ,int cmd,...);
返回值:若成功返回cmd,失敗返回-1;

fcntl函式的五種功能: 

a.cmd = f_dupfd	    複製乙個現存的檔案描述符,新檔案描述符作為函式返回值; eg:fcntl(fd ,f_dupfd);  /  fcntl(fd ,f_dupfd,5);		

b.cmd = f_getfd/f_getfd 獲得/設定檔案描述符標記(fd),新的檔案描述符fd為返回值;

c.cmd = f_getfl/f_setfl 獲得/設定檔案狀態標誌,對應於fd的檔案狀態標誌作為返回值;

eg:int val=fcntl(3,f_getfl);

fcntl(3,f_setfl,val|);

d.cmd = f_fetown/f_setown 獲得/設定檔案非同步i/o所以權

e.cmd = f_setlk/f_setlkw 獲得/設定記錄鎖

(7) stat,fstat,lstat函式

該函式可以獲取檔案的屬性,檔案屬性儲存在結構物件buf中,lstat返回符號鏈結的屬性

#include int stat(const char *path, struct stat *buf); 

int fstat(int filedes, struct stat *buf);

int lstat(const char *path, struct stat *buf);

struct stat結構體用於存放從核心空間struct node結構體中返回的檔案屬性,struct stat結構體中的成員變數對應與struct node每個成員變數。

(8) 檔案描述符複製         

#include int dup(int fd);  //將fd拷貝給當前未被使用的最小的檔案描述符,並返回該檔案描述符

int dup2(int fd,int fd2);

返回值:成功則返回新檔案描述符,出錯返回-1.

函式說明:1)兩個函式可用來複製檔案描述符;

2)複製檔案描述符時即是複製

(9) 檔案對映

#includevoid *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offset);     //將檔案對映到記憶體區域

int munmap(void *start,size_t length); //取消對映

start:對映區的開始位址,設定為0時表示由系統決定對映區的起始位址。

length:對映區的長度。//長度單位是 以位元組為單位,不足一記憶體頁按一記憶體頁處理

prot:期望的記憶體保護標誌,不能與檔案的開啟模式衝突。是以下的某個值,可以通過or運算合理地組合在一起

----prot_exec         //頁內容可以被執行

----prot_read        //頁內容可以被讀取

----prot_write       //頁可以被寫入

----prot_none        //頁不可訪問

flags:指定對映物件的型別,對映選項和對映頁是否可以共享。它的值可以是乙個或者多個標誌位的組合體

fd:有效的檔案描述詞。一般是由open()函式返回,其值也可以設定為-1,此時需要指定flags引數map_anon,表              明進行的是匿名對映。

off_t offset:被對映物件內容的起點。

mmap

()必須以page_size()為單位進行對映,而記憶體也只能以頁為單位進行

對映,若要對映非page_size整數倍的位址範圍,要先進行記憶體對齊,強行以page_size的倍數大小進行對映。

Linux應用程式之按鍵響應

linux中的按鍵檢測通過迴圈讀取裝置檔案 dev input event x 其中x可以為0,1,2 裝置檔案獲取按鍵事件,一般由主線程迴圈獲取按鍵事件,然後通過訊息佇列通知其他子執行緒,從而做出響應。在linux核心中,按鍵事件用input event結構體描述,該結構體在標頭檔案中定義,同時該...

Linux 應用程式 之 IO程式設計(一)

我的linux 環境是windows8.1 vmware6.5.1 fedora14,參考書籍 第六章 我利用乙個ssh軟體ssh secure file transfer client 來從linux傳輸檔案 來張虛擬機器執行fedora的圖 下面步入正題 io最基本操作 1 2 include ...

應用程式配置檔案

這裡主要記錄一下在學習過程中配置檔案的使用,因為是從機房重構接觸到的,就以機房裡的窗體為例子。應用程式配置檔案包含應用程式特定的設定。該檔案包含公共語言執行庫讀取的配置設定 如程式集繫結策略 遠端處理物件等等 以及應用程式可以讀取的設定。應用程式配置檔案的名稱和位置取決於應用程式的宿主,在vs中,配...