天天看點

Linux檔案IO詳解檔案IO

檔案IO

不帶緩存的IO函數:

open

,

read

,

write

,

lseek

close

。每個函數對應核心的一個系統調用,這些函數不是C語言标準,但屬于POSIX接口。

檔案描述符

對Linux而言,所有的打開檔案都由檔案描述符引用。檔案描述符是一個非負整數。當用

open

,

creat

打開檔案時,傳回檔案描述符,對檔案的讀寫操作通過檔案描述符進行。

按照慣例,檔案描述符0與程序的标準輸入結合,檔案描述符1與标準輸出結合,檔案描述符2與标準錯誤結合。在POSIX中,

1

2

用符号常數

STDIN_FILENO

STDOUT_FILENO

STDERR_FILENO

代替。這些常數定義在

<unistd.h>

中。

open

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char* pathname, int o_flag, .../*, mode_t mode */);
           
  • pathname

    : 要打開或建立的檔案的名字
  • o_flag

    : 打開檔案标志(定義在

creat函數

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int creat(const char *pathname, mode_t mode);   //成功時傳回檔案描述符,否則傳回-1
           

早期的

open

函數隻能打開已有的檔案,需要用

creat

函數建立檔案,而且

creat

建立檔案的同時也以隻寫的方式打開了檔案。相當于

open(pathname, O_WRONLY | O_CREAT | O_TRUNC, mode)

;

close

用close函數關閉一個打開檔案。

#include <unistd.h>

int close(int filedes);
           

關閉一個檔案時也釋放該程序加在該檔案的所有記錄鎖。當一個程序終止時,他的所有打開檔案都由核心關閉。

lseek

每個打開檔案都有一個與其關聯的“目前檔案位移量“。它是一個非負整數,用來度量從檔案開始處計算的位元組數。當打開一個檔案時,位移量為0。lseek顯式地定位一個打開檔案的位移,該操作隻改變了作業系統維護的值,不會有實際的IO操作。

以讀寫方式打開的檔案使用一個偏移量,讀或寫都會改變改偏移量。如果使用了O_APPEND标志,每次寫入後都會把偏移量移到末尾。

在打開檔案表裡每個表項有一個目前檔案位移量成員。而檔案描述符複制的結果是兩個檔案描述父共用一個位移量。

#include <sys/types.h>
#include <unistd.h>

off_t lseek(int filedes, off_t offset, int whence); //成功時傳回新的檔案偏移,否則為-1。
           

filedes是要定位的檔案的檔案描述父,whence是基準位置,offset是以基準的偏移量。whence的取值:

- SEEK_SET: 檔案開頭。

- SEEK_CUR: 目前偏移量

- SEEK_END: 檔案末尾加一的位置。

不是所有的檔案都可以用lseek定位偏移,比如管道就不行。

read

#include <unistd.h>

ssize_t read(int filedes, void* buf, size_t n); //成功時傳回讀到的位元組數(包括0),出錯傳回-1。
           

讀資料時預設是阻塞的,如果open時指定O_NONBLOCK那麼是非阻塞的。

有多種情況下,讀取到的位元組數小于指定的位元組數:

- 讀普通檔案是,快到檔案末尾。

- 從終端讀取資料,預設時一次最多一行

- 從網絡中讀時,網絡的部分資料沒到達,隻讀取到達的資料。

讀操作執行完之後,檔案的偏移量後移實際讀得的位元組數。

write

#include <unistd.h>

ssize_t write(int filedes, const void* buf, size_t n); //成功時傳回寫入的位元組數,出錯為-1
           

寫入後檔案偏移後移寫入位元組數。如果打開時O_APPEND選項,則每次寫入時都會自動将偏移移動到末尾再寫入。

注:為了保證完整寫入,需要檢查傳回值是否與n相等。

繼續閱讀