1. 程式人生 > >[IO系統]02 使用者態的檔案IO操作

[IO系統]02 使用者態的檔案IO操作

在工作中,經常會進行檔案建立、更新、刪除等操作,但是作為儲存領域技術人員,我們又對其過程瞭解多少哪。本系列文章將會對檔案操作進行系統的分析和梳理,與大家共同進步。

先來了解使用者態的檔案操作的常用函式。

1. “緩衝”檔案系統 – 使用者態帶快取(與檔案系統沒有關係)

緩衝檔案系統的特點是:在記憶體開闢一個“緩衝區”,為程式中的每一個檔案使用,當執行讀檔案的操作時,從磁碟檔案將資料先讀入記憶體“緩衝區”, 裝滿後再從記憶體“緩衝區”依此讀入接收的變數。執行寫檔案的操作時,先將資料寫入記憶體“緩衝區”,待記憶體“緩衝區”裝滿後再寫入檔案。由此可以看出,記憶體 “緩衝區”的大小,影響著實際操作外存的次數,記憶體“緩衝區”越大,則操作外存的次數就少,執行速度就快、效率高。一般來說,檔案“緩衝區”的大小隨機器而定。

fopen, fclose, fread,fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind等

2.“非緩衝”檔案系統 – 使用者態不帶快取(與檔案系統沒有關係)

緩衝檔案系統是藉助檔案結構體指標(FILE)來對檔案進行管理,通過檔案指標來對檔案進行訪問,既可以讀寫字元、字串、格式化資料,也可以讀寫二進位制資料(openmode:r和ra)。非緩衝檔案系統依賴於作業系統,通過作業系統的功能對檔案進行讀寫,是系統級的輸入輸出,它不設檔案結構體指標(但是有檔案描述符),只能讀寫二進位制檔案,但效率高、速度快,由於ANSI標準不再包括非緩衝檔案系統,因此建議大家最好不要選擇它,只作簡單介紹。

open, close, read,write, getc, getchar, putc, putchar 等

1.1   典型函式

使用者態的檔案操作,主要分為兩類。

POSIX檔案介面操作:

# 開啟檔案,flags 必須包含O_RDONLY, O_WRONLY, or O_RDWR中的任何一個

int open(const char *pathname, intflags);

# 開啟檔案,mode只是在flags中包含O_CREAT時才有效

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

# 定位檔案位置

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

# 讀取檔案內容,檔案位置會隨讀取的位元組數移動

ssize_t read(int fildes, void *buf,size_t nbyte);

# 寫入檔案內容,檔案位置會隨讀取的位元組數移動

ssize_t write(int fildes, const void*buf, size_t nbyte);

# 關閉檔案

int close(int fd);

# 檔案同步

int fsync(int fd);

# 預置檔案大小

int ftruncate(int fd, off_t length);

# 獲得檔案的基本資訊

int fstat(int fd, struct stat *buf);

C99標準檔案操作:

# 檔案開啟操作

FILE *fopen(const char *path, constchar *mode);

#檔案定位操作

int fseek(FILE *stream, long offset,int whence);

# 查詢當前游標位置

long ftell(FILE *stream);

# 將游標位置移動到檔案頭部

void rewind(FILE *stream);

# 檔案讀操作

size_t fread(void *ptr, size_t size,size_t nmemb, FILE *stream);

# 檔案寫操作

size_t fwrite(const void *ptr,size_t size, size_t nmemb,FILE *stream);

# 判斷檔案是否已經讀完

int feof(FILE *stream);

# 按格式讀取檔案流,還有scanf家族的其他函式,比如sscanf可以讀取位元組流

int fscanf(FILE *stream, const char*format, ...);

# 按格式將內容寫入到檔案中,還有sprintf,vprintf等等

int fprintf(FILE *stream, const char*format, ...);

# 直接將不定引數寫入到檔案,相對應的還有讀取函

int vfprintf(FILE *stream, constchar *format, va_list ap);   

# 強迫將緩衝區內的資料寫回引數stream 指定的檔案中.

int fflush(FILE *stream);

# 從檔案結構體指標stream中讀取資料,每次讀取一行,讀到換行符或EOF時停止

char *fgets(char *s, int size, FILE*stream);       NT                                     

# 取得引數stream指定的檔案流所使用的檔案描述符

int fileno(FILE *stream);

# 向指定的檔案寫入一個字串

int fputs(const char *s, FILE*stream);

兩者區別:

1. 前者屬於低階IO操作,後者是高階IO操作。

2. 前者返回一個檔案描述符,後者返回一個檔案指標。

3. 前者無使用者態緩衝,後者有使用者態緩衝。

4. 前者與read, write 等配合使用, 後者與 fread, fwrite等配合使用。

5. 後者是在前者的基礎上擴充而來的,在大多數情況下,用後者。 

其他的檔案操作:

檔案許可權類操作

# 刪除指定路徑的檔案

int remove(const char *pathname);

# 重新命名指定檔案

int rename(const char *old, constchar *new);

#修改檔案的存取時間

int utime(const char *path, conststruct utimbuf *times);

# 獲得檔案的詳細資訊

int stat(const char *restrict path,struct stat *restrict buf);

#開啟資料夾

DIR *opendir(const char *name);

# 讀取目錄內容操作

int readdir_r(DIR *dirp, structdirent *entry, struct dirent **result);

# 關閉資料夾

int closedir(DIR *dirp);

# 獲得當前的絕對路徑

char *getcwd(char *buf, size_tsize);

# 改變檔案許可權

int chmod(const char *path, mode_tmode);

# 改變當前的工作目錄

int chdir(const char *path);

1.2   典型場景

使用者操作的電影場景如下:最常用的

fd = open(…)

lseek(fd…)

write(fd…)

# 或read(fd)

close(fd)

FILE = fopen(…)

fseek(FILE…)

fwrite(FILE…)

# 或fread(FILE)

fclose(FILE)

未完,待續