Unix系統編程文件I/O基礎知識

文件描述符

對於內核而言,所有打開的文件都通過文件描述符引用,文件描述符是一個非負整數,當打開一個現有文件或者創建一個新文件時,內核向進程返回一個文件描述符,當讀、寫一個文件時,使用open或create返回的文件描述符標識該文件,將其傳遞給read或write。

按照慣例,UNIX系統shell把文件描述符0與進程的標準輸入關聯,文件描述符1與標準輸出關聯,文件描述符2與標準錯誤關聯。在符合POSIX.1的應用程序中,幻數0、 1 、2已被標準化,通常把他們替換成符號常量:STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO,這樣可以提高可讀性,常定義在<unistd.h>中。

#include <fcntl.h>
int open(const char *path, int oflag, ... /*mode_t mode*/);
int openat(int fd, const char *path, int oflag, ... /*mode_t mode*/);

兩個函數的返回值:若成功返回文件描述符,若出錯,返回-1

path參數是要打開或創建的文件名字,oflag參數可用來說明此函數的多個選項,用下列一個或多個常量進行“或”運算構成oflag參數(這些常量在頭文件<fcnttl.h>)中定義:

函數lseek

每個打開的文件都有一個與其相關聯的“當前文件偏移量(current file offset)”,它通常是一個非負整數,用以度量從文件開始處計算的字節數,通常讀、寫操作都從當前偏移量處開始,並使偏移量增加所讀寫的字節數,按照系統默認設定,當打開一個文件時,除非指定O_APPEND選項,否則該偏移量被設置爲0,可以調用lseek顯示地爲一個打開文件設置偏移量

#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);

若成功,返回新的文件偏移量,若出錯,返回-1。

對參數offset的解釋與參數whence相關。

1、若whence是SEEK_SET(0),則將該文件的偏移量設置爲距文件開始處offset個字節。

2、若whence是SEEK_CUR(1),則將該文件的偏移量設置爲其當前值加offset,offset可正可負。

3、若whence是SEEK_END(2),則將該文件的偏移量設置爲文件長度加offset,offset可正可負。

若lseek執行成功,則返回新的文件偏移量,爲此可以使用下列方式確定打開文件的當前偏移量:

off_t currpos;

currpos = lseek(fd, 0, SEEK_CUR);

這種方式也可以用來確定所涉及的文件是否可以設置偏移量。如果文件描述符指向的是一個管道、FIFO或網絡套接字,則lseek返回-1,並將errno設置爲ESPIPE。

關於文件偏移量大於文件長度的說明:如果文件偏移量大於文件的長度,對該文件的下一次寫,將加長該文件,並在文件中構成一個空洞,這一點是允許的,位於文件中但沒有寫過的字節都被讀爲0。

文件中的空洞並不要求在磁盤上佔用存儲區。具體處理方式與文件系統的實現有關,當定位到超出文件尾端之後寫時,對於新寫的數據需要分配磁盤塊,但是對於源文件尾端和新開始寫位置之間的部分(空洞部分)則不需要分配磁盤塊。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章