天天看點

open/close read/write lseek

open/close

檔案描述符

一個程序啟動之後,預設打開三個檔案描述符:

#define  STDIN_FILENO     	0
#define  STDOUT_FILENO    	1
#define  STDERR_FILENO    	2
           

新打開檔案傳回檔案描述符表中未使用的最小檔案描述符, 調用open函數可以打開或建立一個檔案, 得到一個檔案描述符.

open函數

函數描述: 打開或者建立一個檔案

函數原型:

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

函數參數:

pathname:參數是要打開或建立的檔案名,和fopen一樣, pathname既可以是相對路徑也可以是絕對路徑。

flags :參數有一系列常數值可供選擇, 可以同時選擇多個常數用按位或運算符連接配接起來, 是以這些常數的宏定義都以O_開頭,表示or。

**必選項:**以下三個常數中必須指定一個, 且僅允許指定一個。

O_RDONLY 隻讀打開

O_WRONLY 隻寫打開

O_RDWR 可讀可寫打開

以下可選項可以同時指定0個或多個, 和必選項按位或起來作為flags參數。可選項有很多, 這裡隻介紹幾個常用選項:

O_APPEND 表示追加。如果檔案已有内容, 這次打開檔案所寫的資料附加到檔案的末尾而不覆寫原來的内容。

O_CREAT 若此檔案不存在則建立它。使用此選項時需要提供第三個參數mode, 表示該檔案的通路權限。

檔案最終權限:mode & ~umask

O_EXCL 如果同時指定了O_CREAT,并且檔案已存在,則出錯傳回。

O_TRUNC 如果檔案已存在, 将其長度截斷為為0位元組。

O_NONBLOCK 對于裝置檔案, 以O_NONBLOCK方式打開可以做非阻塞I/O(NonblockI/O),非阻塞I/O。

函數傳回值:

成功: 傳回一個最小且未被占用的檔案描述符

失敗: 傳回-1, 并設定errno值.

close函數

函數描述: 關閉檔案

函數原型: `

函數參數: fd檔案描述符

函數傳回值:

成功傳回0

失敗傳回-1, 并設定errno值.

需要說明的是,當一個程序終止時, 核心對該程序所有尚未關閉的檔案描述符調用close關閉,是以即使使用者程式不調用close, 在終止時核心也會自動關閉它打開的所有檔案。但是對于一個長年累月運作的程式(比如網絡伺服器), 打開的檔案描述符一定要記得關閉, 否則随着打開的檔案越來越多, 會占用大量檔案描述符和系統資源。

read/write

read函數

函數描述: 從打開的裝置或檔案中讀取資料

函數原型:

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

函數參數:

fd: 檔案描述符

buf: 讀上來的資料儲存在緩沖區buf中

count: buf緩沖區存放的最大位元組數

函數傳回值:

>0:讀取到的位元組數

=0:檔案讀取完畢

-1: 出錯,并設定errno

write

函數描述: 向打開的裝置或檔案中寫資料

函數原型:

函數參數:

fd:檔案描述符

buf:緩沖區,要寫入檔案或裝置的資料

count:buf中資料的長度

函數傳回值:

成功:傳回寫入的位元組數

錯誤:傳回-1并設定errno

lseek

所有打開的檔案都有一個目前檔案偏移量(current file offset),以下簡稱為cfo. cfo通常是一個非負整數, 用于表明檔案開始處到檔案目前位置的位元組數. 讀寫操作通常開始于 cfo, 并且使 cfo 增大, 增量為讀寫的位元組數. 檔案被打開時, cfo 會被初始化為 0, 除非使用了 O_APPEND.

使用 lseek 函數可以改變檔案的 cfo.

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

函數描述: 移動檔案指針

函數原型:

函數參數:

fd:檔案描述符

參數 offset 的含義取決于參數 whence:

如果 whence 是 SEEK_SET,檔案偏移量将設定為 offset。

如果 whence 是 SEEK_CUR,檔案偏移量将被設定為 cfo 加上 offset,offset 可以為正也可以為負。

如果 whence 是 SEEK_END,檔案偏移量将被設定為檔案長度加上 offset,offset 可以為正也可以為負。

函數傳回值: 若lseek成功執行, 則傳回新的偏移量。

lseek函數常用操作

檔案指針移動到頭部

擷取檔案指針目前位置

擷取檔案長度

lseek實作檔案拓展

off_t currpos;

// 從檔案尾部開始向後拓展1000個位元組

// 額外執行一次寫操作,否則檔案無法完成拓展