UNIX 檔案I O總結

2021-07-02 06:49:37 字數 2825 閱讀 5149

輸入是從i/o裝置拷貝資料到主存,輸出是從主存拷貝資料到i/o裝置。

乙個檔案就是乙個位元組序列。

所有的i/o裝置,如網路、磁碟、和終端,都被模型化為檔案,而所有的輸入和輸出都被當做想對應的檔案的讀寫來執行。

1、iso c的i/o操作是帶快取的,而posix標準的i/o操作是指真正發生了系統呼叫,是不帶快取的

2、檔案描述

(1)是對乙個已開啟檔案的引用,是由shell定義,unix沿用,與核心無關。

(2)檔案描述符是乙個非負整數,0、1、2已被標準輸入、標準輸出和標準錯誤關聯

(3)檔案描述符是在某乙個程序/執行緒中對乙個檔案的描述,同乙個檔案在不同程序/執行緒中的描述符可以不同,這也是檔案共享的理論基礎

3、檔案開啟操作 open()和openat()

(1)返回檔案描述符或者-1

int open(char *filename, int flags, mode_t mode);
int openat(int fd,char *filename, int flags, mode_t mode)
(2)flags引數

o_rdonly: reading only

o_wronly: writing only

o_rdwr: reading and writing 

(3)openat()的引入是為了解決 

open()中檔案路徑為相對路徑時,不再只能開啟當前工作目錄的檔案的問題

避免兩個函式呼叫相關聯引起的檔案覆蓋問題

fd為引數指出了相對路徑在檔案系統的起始位址

4、建立檔案

int creat(const char *path,mode_t mode);

等效於open(path,o_wronly|o_creat|o_trunc,mode)

creat()以只寫的方式建立並開啟檔案,不能立即讀取檔案,所以最好用第二種方法。

5、檔案關閉

int close(int fd);
關閉檔案,釋放記錄鎖。程序關閉時,核心會自動關閉該程序的所有呼叫檔案,所以有時不比顯示關閉檔案。

6、檔案偏移函式

off_t lseek(int fd,off_t offset, int whence);

whence:

seek_set     檔案操作從offset處開始

seek_cur   檔案已有偏移+offset

seek_end  檔案長度+offset

offset 可正負

off_t的型別決定了乙個檔案的最大長度,32位時,有符號位,最大長度為2^31-1,2gb

7、讀操作

ssize_t read(int fd, void *buf,size_t nbytes);

(1)返回-1,出錯;返回0,到達檔案末尾;返回正整數,讀取位元組數

(2)設定讀取nbytes,在不同裝置上可以讀取的位元組數往往不能滿足nbytes

8、寫操作

ssize_t write(int fd, void *buf,size_t nbytes);
(1)出錯,返回-1,成功返回寫的位元組數

9、檔案共享

(1)每個程序的程序表有乙個表項記錄開啟檔案的檔案描述符表,不同的描述符,都對應乙個不同的檔案表

(2)檔案表記錄檔案的狀態(讀、寫、阻塞、同步、新增等)、檔案偏移量和指向檔案v結點結構的指標,仍然屬於當前程序

(3)檔案v結點結構是描述具體檔案的資訊載體。包含檔案型別、對此檔案的各種操作、檔案作者、長度、指向檔案所在磁碟位置的指標等。

檔案v結點也是對具體檔案系統的抽象,不屬於某乙個程序。

這樣,不同程序可以對同乙個檔案v結點結構進行操作,在處理好同步的情況下,可以實現不同程序/執行緒的檔案共享。

10、檔案描述符的複製

共享同乙個檔案表

int dup(int fd);

int dup2(int fd, int fd2);

dup()函式返回fd檔案符描述檔案的最小可用檔案描述符,失敗返回-1

dup2(fd,fd2)函式返回指定檔案描述符fd2,如果fd2被占用,則先將其關閉,如果fd2=fd,返回fd2。失敗返回-1。

11、快取區重新整理

延遲寫:

核心中設有快取區快取記憶體或者頁快取記憶體,大多數i/o操作都要經過快取區,再排入讀寫佇列,最後由系統守護程序定時呼叫sync函式寫入磁碟

void sync(void);

int fsync(int fd);

sync將修改過的快取區排入寫佇列,就返回,不管是否寫入磁碟。寫佇列由系統守護程序update維護

fsync(fd)只將檔案描述符fd描述的檔案的修改部分立即呼叫i/o操作寫入磁碟。

12、改變已開啟檔案的屬性

int fcntl(int fd,int cmd,.../*int arg*/);
該函式有五種功能:

(1)輔助乙個已有的描述符,功能同dup() dup2()函式

(2)獲取/設定檔案描述符的標誌,即改變fd_cloexec的值,0開,1關閉

(3)獲取/設定檔案狀態

(4)獲取/設定非同步i/o的所有權

(5)獲取/設定記錄鎖

13、ioctl函式

ioctl是裝置驅動程式中對裝置的i/o通道進行管理的函式。所謂對i/o通道進行管理,就是對裝置的一些特性進行控制。

詳細參考:

Unix 標準I O總結和與檔案I O的比較

我們可以將檔案i o視為系統呼叫,核心要執行i o操作,這裡涉及到頁快取 快取記憶體區 的概念,檔案i o執不執行與快取區有關。而標準i o是對系統i o呼叫的封裝,標準i o也有快取區 行快取的概念。正是由於這二級的快取模式。導致標準i o的效率很低。當開啟乙個流時,標準i o函式fopen返回乙...

unix 檔案I O之詮釋

unix系統中的大多數檔案i o只需用到5個函式 open,read,write,lseek以及close.其中open,create,fcntl,sync,fdatasync五個函式包含在標頭檔案中.其它的close,lseek,read,write,pread,pwrite,dup,dup2包含...

Unix高階程式設計 檔案I O

第3章檔案i o 3.1檔案描述符 fd stdin fileno 標準輸入 stdout fileno 標準輸出 stderr fileno 標準錯誤 乙個程序最多開啟63個檔案 3.2 open函式 include int open const char pathname,int oflag,m...