1. 程式人生 > >Linux檔案IO詳解

Linux檔案IO詳解

檔案IO

不帶快取的IO函式:open, read, write, lseekclose。每個函式對應核心的一個系統呼叫,這些函式不是C語言標準,但屬於POSIX介面。

檔案描述符

對Linux而言,所有的開啟檔案都由檔案描述符引用。檔案描述符是一個非負整數。當用open,creat開啟檔案時,返回檔案描述符,對檔案的讀寫操作通過檔案描述符進行。
按照慣例,檔案描述符0與程序的標準輸入結合,檔案描述符1與標準輸出結合,檔案描述符2與標準錯誤結合。在POSIX中,012用符號常數STDIN_FILENOSTDOUT_FILENOSTDERR_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相等。