[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)
未完,待續